Reputation: 2711
I am creating some properties and came across a scenario I haven't seen before.
Consider
private double _temperature;
private double _maxTemp;
public double Temperature
{
get { return _temperature; }
set { _temperature = value; }
}
public double MaxTemp
{
get { return _maxTemp; }
set { _maxTemp = value; }
}
public bool IsTempToHigh
{
get
{
if (_temperature < _maxTemp)
return true;
else
return false;
}
}
No problem here but I have a lot of properties in this fashion and I rewrote it into this:
public double Temperature { get; set; }
public double MaxTemp { get; set; }
public bool IsTempToHigh
{
get
{
if (Temperature < MaxTemp)
return true;
else
return false;
}
}
Quite a bit cleaner in my opinion and it seems to works just as fine. However, I nerver seen or noticed anyone using the property names directly in gettes (or setters), so is it safe to use or might there be any pitfalls.
Also why does this compile but gives an StackOverflowException:
public double Value
{
get { return Value; }
set { Value = value; }
}
Upvotes: 1
Views: 1907
Reputation: 16926
It is fine to have a property that evaluates 2 other properties. Of course you easily use a method to do the same job. E.g. change
public bool IsTempToHigh
{
get
{
if (_temperature < _maxTemp)
return true;
else
return false;
}
}
to
public bool IsTempToHigh()
{
return _temperature > _maxTemp;
}
(note: I have changed your < to > assuming this to be correct)
You get an exception on your value because you are set the object itself. This then changes it's value, so it tries to set itself again....
so this is wrong...
public double Value
{
get { return Value; }
set { Value = value; }
}
but either of the following would be ok
public double Value { get; set;}
or
private double _myVal;
public double MyValue
{
get{ return _myVal;}
set{ _myVal = value;}
}
Upvotes: 1
Reputation: 1499840
If you mean in terms of IsTempTooHigh
, that's fine (although the condition is the wrong way round for the name). It's entirely valid to refer to one property within another, although you need to be careful that you don't make it recursive. Your autoimplemented properties still have backing fields - they've just been generated by the compiler for you rather than being present in your source code.
I'd rewrite your computed property without the if
, mind you:
public bool IsTempTooHigh { get { return Temperature >= MaxTemp; } }
Or in C# 6:
public bool IsTempTooHigh => Temperature >= MaxTemp;
As for the stack overflow, it's simplest to imagine they were methods instead:
public double GetValue()
{
return GetValue();
}
public void SetValue(double value)
{
SetValue(value);
}
Can you see why calling either of those would cause a stack overflow? Well, it's just the same for properties - they're just methods with a bit of metadata linking them, basically.
Upvotes: 7
Reputation: 3133
It's safe and fine to use property names in private member functions where you currently use the data members.
That code throws a StackOverFlow exception because by assigning to Value
you're actually calling the property. Instead, change the name of the underlying data member to be _value
:
public double Value {
get { return _value; }
set { _value = value; }
}
Upvotes: 1
Reputation: 156928
You can easily use other properties, fields and methods inside your properties. No worries at all.
Your second code block however, calls the same property over and over again. You are trying to mix auto-implemented properties with hand-written properties. That is not possible.
Or the compiler generates backing fields for you (when you use auto-implemented properties) or you have to create them yourself (hand-written properties).
So it is either this:
public double Value { get; set; }
Or:
private double _value;
public double Value
{
get { return _value; }
set { _value = value; }
}
Upvotes: 2
Reputation: 540
First question: Yes your change makes the code clearer in my opinion. A valid case for using backing fields is if you want immutability. The fields are then readonly and you have no setters.
Second question: Your setter calls your setter. Which calls your setter. Which calls your setter. And so on. After a while the stack becomes too large and you get the error. :)
Upvotes: 2