no, properties shouldn't perform a lot of work ...
"Should" they? That's a squishy question.
They certainly can, and there aren't a "lot" of reasons not to. Stack overflows are one good reason to avoid doing a lot of work inside a property accessor, but if your code is otherwise readable and your intent easily communicable, there's no hard and fast rule that says not to.
The general rule of thumb is properties should not be expensive to call. If they are expensive to call, make them into a getter instead. This can't always be followed, you definitely need to use judgment.
Properties are really just syntactic sugar. As a best practice I like to keep them very simple and not put a lot of code in them. However there is no technical reason for that. In the end they are just functions that get executed. What you need to ask when you use them is what is going to be most maintainable and intuitive to those who come after you.
I think the best rule to go by is that they shouldn't throw ecxeptions, and also don't have side effects. For example if you keep calling the getter, and nothing else changes the returned value shouldn't change. Note that ‘DateTime.Now‘ doesn't follow this rule, but probably should have.
methods are used instead, one should not be that surprised that something non-trivial might be going on under the hood
due to Properties is just a syntactic sugar over exactly the same Set... and Get... methods (which produced by compiler when IL is made) - there is no any difference. If you would implement some logic in SetFoobar - do it in Foobar { set { ... } } too
However, now that C# gave the world Properties, it seems silly to use getter and setter methods instead.
Before thinking about how expensive properties should be, I would advise you to think about whether the concept you are modeling is best represented as a "property of something". Properties exist in the language to express attribution of other entities - if SomeValue
is not logically a property of the type it belongs to, then you should consider using getter/setter methods instead.
Should properties in C# perform a lot of work?
Having said that, it helps to make properties inexpensive when possible. Most developers expect properties to be efficient wrappers around some internal state of the type they belong to. Violating this expectation makes it harder for developers to write well performing code that uses the property. For example, if a property is used in as a conditio of a for
loop it will be evaluated on each iteration - if it's expensive ... well that can be bad.
Properties are also often accessed in the debugger - you don't want properties to perform expensive logic as this can inhibit debugging. Property getters that perform operations with side effects (like querying a database, for example) are generally a bad practice as well, because they can introduce heisenbugs when inspecting the behavior of an application in the debugger.
What is the alternative.
You may also want to read up on this answer which provides some good general guidelines for property design. I would also advise you to read Choosing Between Properties and Methods in the .NET design guidelines on MSDN.
Sometimes it makes sense to create a property which is read-only (no setter) but where one or more separate methods exists that set the internal state related to that property. Whether to use this idiom depends on whether the operations on your object are exposed semantically as "changing state" or "performing activity". When it's the later, I tend to use methods (rather than property setters) to express this behavior.
The person using the class you created has no idea as to what is the implementation. He might use User.ID over and over again without knowing each of those is a DB call.
You see, 99% of the time, properties are nothing more than variables with an extra line of code at best, so developers treat them as such. It's considered good practice to refactor a property into a method if it's expensive in any way. You never know what a method is hiding, and (good) developers conserve on calling methods when they can cache results from previous callings.
The exact amount of too much work is debatable. The best answer is that properties should rather perform less work than more work :)
One thing that Get Properties should never do is to change the state of the object.
As a user of a class, I expect properties to be not expensive - because as the name implies they just get/set a value of an object. In contrast, when I call a method on an object, I am aware that it will "do something" and might be expensive.
One thing, that should always be true for properties, is that property-getter should be free of side-effects. E.g. a property-getter should return the same value, even if I call it 10 successive times. This is best visible when you see this usage of a property:
int result = obj.SomeNumber + obj.SomeNumber;
// I expect SomeNumber to return the same value on both calls