views:

100

answers:

4

Is there any way in C# to mark a property as deterministic?

The reason I ask is that I often find myself declaring a local variable and reading a property into it, instead of accessing the property multiple times.

Is there any way that I can decorate the property as deterministic, such that the compiler could then optimize multiple accesses to that property? I am guessing in such a scenario that the class would need to be immutable, and decorated as such.

Is this something that even exists or am I clutching at straws?

A: 

Unless the backing field of your property is readonly, how are you going to account for threading issues?

Daren Thomas
+5  A: 

There is no mechanism in C# that allows you to introduce const property getters, i.e. getters that do not change the state of the object.

The Microsoft documentation simply recommends not to introduce any side-effects in your getters:

It is a bad programming style to change the state of the object by using the get accessor. For example, the following accessor produces the side effect of changing the state of the object every time that the number field is accessed.

private int number;
public int Number
{
    get
    {
        return number++;   // Don't do this
    }
}

As mentioned by Daren, another aspect to consider is multi-threading (unless your object is truly immutable). What if another thread changed the object state so that the getter should return a different value on the second call? There is no easy way for the compiler to make any guarantees, e.g. in the scenario below:

class List
{
    IList data;

    // called several times on thread A
    // property has no side-effects
    public int Count { get data.Length; }

    // called several times on thread B
    public void Add(object o)
    {
        data.Add(o);
    }
}
0xA3
DateTime.Now is a property that does not change state, but changes value anyway. Many other properties reflect state that can be changed by other means than just the get setter.
Albin Sunnanbo
@Albin Sunnanbo: `DateTime.Now` is not a good example here because it is static and it *returns* a new value type. There is no state nor value changed. The thing is that the OP wants to have a mechanism that guarantees that subsequent calls to the same property (at least in a single-threaded environment) yield the same result.
0xA3
+1, this gets a vote, definitely, but the thing I am really wondering is, if you have followed the recommendations, is there any way to coerce the compiler into realising that multiple property gets will return the same value, and to therefore compile them as if you were declaring a local variable first if you use the same property value multiple times in the same scope.
Matt Whitfield
+2  A: 

I guess you're looking for readonly, however I'm not sure about how the performance is compared to a local variable. And it is only applicable to fields, not properties.

Besides readonly does not imply determinism.

private readonly List<string> fixedList = new List<string>();

just means that the fixedList object can not be replaced, but the content can still be changed.

Albin Sunnanbo
+7  A: 

If the property is simple, like an implicit property:

public int X { get; set; }

or reading from a local variable:

public int X { get { return _x; } }

then the compiler will optimise the code so that there is no difference between accessing the property multiple times and putting the property in a variable and access that.

I verified this by comparing 100 million iterations of accessing a property ten times and copying the property to a variable and access that ten times, and there is no measuarable difference at all.

Generally properties should be leight-weight, so that you don't have to expect any heavy processing each time you access it. If the value for the property is costly to get, the class should cache the value internally so that reading the property only makes the costly operation the first time (lazy loading pattern).

If a property is costly to get each time, it shouldn't be a property at all, but a getter method.

Guffa
+1 - Just one question - if the compiler does do this optimisation anyway, then how would it account for changes to the object on non-immutable objects - whether that was from the same thread or not? Is it possible that you just validated that property gets on a simple property cost an intensely small amount, in which case I should stop being anal about it? :)
Matt Whitfield
@Matt Whitfield: When the code is optimised, the simple property will be interned. Reading the property will actually not call a property getter to return the value, but get the value directly, just as if you were accessing a public variable in the class. In the C# code you get the abstraction and isolation you want in OOP code, but in the compiled code you get the speed of public variables. :)
Guffa
@Guffa - thanks - I'm going to accept this because that comment you have there is the bit that gives me the understanding I was looking for when I asked the question.
Matt Whitfield