8

When a property is read from or is assigned to, one would not expect it to perform a lot of work. When setSomeValue(...) and getSomeValue(...) methods are used instead, one should not be that surprised that something non-trivial might be going on under the hood. However, now that C# gave the world Properties, it seems silly to use getter and setter methods instead. What is your take on this? Should I mark this Q as a community wiki?

Thanks.

EDIT:

In my case it is not expensive to call, but it triggers setting a related property in another class and possibly writing a short message to a log file (if URL is blank). Is that too much work for a property? What is the alternative.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
Hamish Grubijan
  • 10,562
  • 23
  • 99
  • 147
  • Is that "related property in another class" changed by a property-setter or -getter? – M4N May 06 '10 at 22:44
  • It is changed by a property ... it actually gets more weird. That topmost property comes from a .config xml file and is populated by an XML [de]serializer. This might leave little choice for me. I am glad that I asked this question though, it is good to think about these things. – Hamish Grubijan May 06 '10 at 22:48

10 Answers10

20

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 condition 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 exist 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 latter, I tend to use methods (rather than property setters) to express this behavior.

participant
  • 2,923
  • 2
  • 23
  • 40
LBushkin
  • 129,300
  • 32
  • 216
  • 265
  • 1
    Side note: You can force the debugger to not evaluate property in case the property has a side-effect using DebuggerBrowsable attribute. See: https://lostechies.com/jamesgregory/2009/08/18/debugger-property-evaluation-side-effects/ – Gnbrkm41 Jan 17 '19 at 11:28
4

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.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • Hm ... in my case it is not expensive to call, but it triggers setting a related property in another class and possibly writing a short message to a log file (if URL is blank). Is that too much work for a property? What is the alternative? – Hamish Grubijan May 06 '10 at 22:31
  • @Hamish Grubijan it will usually be clearer if you expose a properly named operation/method in your class. Specially as you are mentioning, it has some other underlying effects. – eglasius May 06 '10 at 22:34
4

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.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
  • +1 for the get not changing the state of the object ... yes, I've seen it out there - *has a flashback of nightmare code out there* – eglasius May 06 '10 at 22:39
  • Yeah, get one of those buggers in the debugger watchlist and you will be tearing your hair out. – Igor Zevaka May 06 '10 at 22:41
  • Wow, I can imagine how much that would stink. Not that I would consciously try to come up with a getter that changes state, but it is funny to think about. – Hamish Grubijan May 06 '10 at 22:50
3

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

zerkms
  • 249,484
  • 69
  • 436
  • 539
2

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.

Rubys
  • 3,167
  • 2
  • 25
  • 26
1

no, properties shouldn't perform a lot of work ...

eglasius
  • 35,831
  • 5
  • 65
  • 110
  • Please elaborate. I don't think there are exact rules in software engineering; there must be some gray area. Even defining what is "a lot of work" and what is "some work" can be tricky. – Hamish Grubijan May 06 '10 at 22:29
1

"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.

andrewbadera
  • 1,372
  • 9
  • 19
1

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.

Jason Webb
  • 7,938
  • 9
  • 40
  • 49
  • Pretty comments make up for ugly code sometimes. I am considering adding comments where this particular property is being called (just one place for now) and warning that some extra work will be done. – Hamish Grubijan May 06 '10 at 22:35
  • Good point. But at the end of the day, you may still have ugly hard to maintain code. I would proceed with caution. – Jason Webb May 06 '10 at 22:54
1

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.

Sander Rijken
  • 21,376
  • 3
  • 61
  • 85
  • Can a setter throw an exception? What if the odds are small? Unlike Java, .Net does not force you to catch all exceptions, so this can be at least partially ambiguous. – Hamish Grubijan May 06 '10 at 22:37
  • 2
    Both a setter and a getter can do it. The framework design guidelines say: *avoid throwing exceptions from getters* and: *preserve the previous value if a property setter throws an exception* – Sander Rijken May 07 '10 at 08:30
  • But .NET avoid this rule: IsSecurityCritical can throw NotSupportedException: http://msdn.microsoft.com/de-de/library/system.reflection.emit.typebuilder.issecuritycritical.aspx – hellboy Sep 29 '13 at 19:04
1

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
M4N
  • 94,805
  • 45
  • 217
  • 260
  • 1
    Side effects is more about what the property does to the object than what value the property returns. In GUI frameworks, for example, touching a property may cause the window handle of the control to be created. That's a side effect. – dthorpe May 06 '10 at 22:46
  • It is easy to convince me that a getter part of property should not have side effects and should return the same thing. I am not sure if setter property has to obey the same. Maybe some parameter must only be set once throughout program execution and should complain subsequently. – Hamish Grubijan May 06 '10 at 22:54
  • @Hamish: of course this is mostly (only) valid for property-getters. Corrected the answer. – M4N May 06 '10 at 23:16