tags:

views:

2961

answers:

11

In his excellent book, CLR Via C#, Jeffrey Richter said that he doesn't like properties, and recommends not to use them. He gave some reason, but I don't really understand. Can anyone explain to me why I should or should not use properties? In C# 3.0, with automatic properties, does this change?

As a reference, I added Jeffrey Richter's opinions:

• A property may be read-only or write-only; field access is always readable and writable. If you define a property, it is best to offer both get and set accessor methods.

• A property method may throw an exception; field access never throws an exception.

• A property cannot be passed as an out or ref parameter to a method; a field can. For example, the following code will not compile:

using System;
public sealed class SomeType {
private static String Name {
get { return null; }
set {}
}
static void MethodWithOutParam(out String n) { n = null; }
public static void Main() {
// For the line of code below, the C# compiler emits the following:
// error CS0206: A property or indexer may not
// be passed as an out or ref parameter
MethodWithOutParam(out Name);
}
}

• A property method can take a long time to execute; field access always completes immediately. A common reason to use properties is to perform thread synchronization, which can stop the thread forever, and therefore, a property should not be used if thread synchronization is required. In that situation, a method is preferred. Also, if your class can be accessed remotely (for example, your class is derived from System.MashalByRefObject), calling the property method will be very slow, and therefore, a method is preferred to a property. In my opinion, classes derived from MarshalByRefObject should never use properties.

• If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time. The System.DateTime class has a readonly Now property that returns the current date and time. Each time you query this property, it will return a different value. This is a mistake, and Microsoft wishes that they could fix the class by making Now a method instead of a property.

• A property method may cause observable side effects; field access never does. In other words, a user of a type should be able to set various properties defined by a type in any order he or she chooses without noticing any different behavior in the type.

• A property method may require additional memory or return a reference to something that is not actually part of the object's state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object's state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.

+10  A: 

I don't see any reasons why you shouldn't use Properties in general.

Automatic properties in C# 3+ only simplify syntax a bit (a la syntatic sugar).

Koistya Navin
please, read pages 215-216 in that book. I'm sure that you know who's Jeffrey Richter!
Vimvq1987
I have read (CLR via C#, 2nd Ed.), don't agree with his position and don't see real reasons do not use properties!
abatishchev
It's a good book, but i don't agree with the author in this moment.
Koistya Navin
One moment, reading this page..
Koistya Navin
Where is exactly that place where author suggests not to use Properties? Have not found anything on p.215-217
Koistya Navin
I added Jeffrey's opinions in my question :). You can find it in pages 215-216 in print edition :)
Vimvq1987
+74  A: 

Jeff's reason for disliking properties is because they look like fields - so developers who don't understand the difference will treat them as if they're fields, assuming that they'll be cheap to execute etc.

Personally I disagree with him on this particular point - I find properties make the client code much simpler to read than the equivalent method calls. I agree that developers need to know that properties are basically methods in disguise - but I think that educating developers about that is better than making code harder to read using methods. (In particular, having seen Java code with several getters and setters being called in the same statement, I know that the equivalent C# code would be a lot simpler to read. The Law of Demeter is all very well in theory, but sometimes foo.Name.Length really is the right thing to use...)

(And no, automatically implemented properties don't really change any of this.)

This is slightly like the arguments against using extension methods - I can understand the reasoning, but the practical benefit (when used sparingly) outweighs the downside in my view.

Jon Skeet
Thanks a lot for you answer! About arguments against using extension methods: are you talking about some Jeffrey Richter's topic or in abstract?
abatishchev
@abatishchev: It was just a general point about extension methods. It's not directly related to properties.
Jon Skeet
A: 

That reason must have been given within a very specific context. It's usually the other way round - it is recomended to use properties as they give you a level of abstraction enabling you to change behaviour of a class without affecting its clients...

Rashack
+7  A: 

I haven't read the book, and you haven't quoted the part of it you don't understand, so I'll have to guess.

Some people dislike properties because they can make your code do surprising things.

If I type Foo.Bar, people reading it will normally expect that this is simply accessing a member field of the Foo class. It's a cheap, almost free, operation, and it's deterministic. I can call it over and over, and get the same result every time.

Instead, with properties, it might actually be a function call. It might be an infinite loop. It might open a database connection. It might return different values every time I access it.

It is a similar argument to why Linus hates C++. Your code can act surprising to the reader. He hates operator overloading: a + b doesn't necessarily mean simple addition. It may mean some hugely complicated operation, just like C# properties. It may have side effects. It may do anything.

Honestly, I think this is a weak argument. Both languages are full of things like this. (Should we avoid operator overloading in C# as well? After all, the same argument can be used there)

Properties allow abstraction. We can pretend that something is a regular field, and use it as if it was one, and not have to worry about what goes on behind the scenes.

That's usually considered a good thing, but it obviously relies on the programmer writing meaningful abstractions. Your properties should behave like fields. They shouldn't have side effects, they shouldn't perform expensive or unsafe operations. We want to be able to think of them as fields.

However, I have another reason to find them less than perfect. They can not be passed by reference to other functions.

Fields can be passed as ref, allowing a called function to access it directly. Functions can be passed as delegates, allowing a called function to access it directly.

Properties... can't.

That sucks.

But that doesn't mean properties are evil or shouldn't be used. For many purposes, they're great.

jalf
My argument is that you shouldn't assume it's a field to start with - because if you're calling it from any other class, you shouldn't have access to non-constant fields anyway, because they should be private. (There's also the naming convention to inform you.)
Jon Skeet
Yeah, I agree. The argument seems to boil down to "I'm used to this syntax being used solely for fields. Therefore, extending it to cover other cases is bad". And the obvious answer is "Well, get used to it covering other cases then, and it won't be bad". ;)
jalf
+1  A: 

Personally I only use properties when creating simple get / set methods. I stray away from it when coming to complicated data structures.

steve
+1  A: 

I don't agree with Jeffrey Richter, but I can guess why he doesn't like properties (I haven't read his book).

Even though, properties are just like methods (implementation-wise), as a user of a class, I expect that its properties behave "more or less" like a public field, e.g:

  • there's no time-consuming operation going on inside the property getter/setter
  • the property getter has no side effects (calling it multiple times, does not change the result)

Unfortunately, I have seen properties which did not behave that way. But the problem are not the properties themselves, but the people who implemented them. So it just requires some education.

M4N
+4  A: 

It's just one person's opinion. I've read quite a few c# books and I've yet to see anyone else saying "don't use properties".

I personally think properties are one of the best things about c#. They allow you to expose state via whatever mechanism you like. You can lazily instantiate the first time something is used and you can do validation on setting a value etc. When using and writing them, I just think of properties as setters and getters which a much nicer syntax.

As for the caveats with properties, there are a couple. One is probably a misuse of properties, the other can be subtle.

Firstly, properties are types of methods. It can be surprising if you place complicated logic in a property because most users of a class will expect the property to be fairly lightweight.

E.g.

public class WorkerUsingMethod
{
   // Explicitly obvious that calculation is being done here
   public int CalculateResult()
   { 
      return ExpensiveLongRunningCalculation();
   }
}

public class WorkerUsingProperty
{
   // Not at all obvious.  Looks like it may just be returning a cached result.
   public int Result
   {
       get { return ExpensiveLongRunningCalculation(); }
   }
}

I find that using methods for these cases helps to make a distinction.

Secondly, and more importantly, properties can have side-effects if you evaluate them while debugging.

Say you have some property like this:

public int Result 
{ 
   get 
   { 
       m_numberQueries++; 
       return m_result; 
   } 
}

Now suppose you have an exception that occurs when too many queries are made. Guess what happens when you start debugging and rollover the property in the debugger? Bad things. Avoid doing this! Looking at the property changes the state of the program.

These are the only caveats I have. I think the benefits of properties far outweigh the problems.

Mark Simpson
+11  A: 

Well, lets take his arguments one by one:

A property may be read-only or write-only; field access is always readable and writable.

This is a win for properties, since you have more fine-grained control of access.

A property method may throw an exception; field access never throws an exception.

While this is mostly true, you can very well call a method on a not initialized object field, and have an exception thrown.

• A property cannot be passed as an out or ref parameter to a method; a field can.

Fair.

• A property method can take a long time to execute; field access always completes immediately.

It can also take very little time.

• If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time.

Not true. How do you know the field's value has not changed (possibly by another thread)?

The System.DateTime class has a readonly Now property that returns the current date and time. Each time you query this property, it will return a different value. This is a mistake, and Microsoft wishes that they could fix the class by making Now a method instead of a property.

If it is a mistake it's a minor one.

• A property method may cause observable side effects; field access never does. In other words, a user of a type should be able to set various properties defined by a type in any order he or she chooses without noticing any different behavior in the type.

Fair.

• A property method may require additional memory or return a reference to something that is not actually part of the object's state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object's state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.

Most of the protestations could be said for Java's getters and setters too --and we had them for quite a while without such problems in practice.

I think most of the problems could be solved by better syntax highlighting (i.e differentiating properties from fields) so the programmer knows what to expect.

foljs
+2  A: 

I can't help picking on the details of Jeffrey Richter's opinions:

A property may be read-only or write-only; field access is always readable and writable.

Wrong: Fields can marked read-only so only the object's constructor can write to them.

A property method may throw an exception; field access never throws an exception.

Wrong: The implementation of a class can change the access modifier of a field from public to private. Attempts to read private fields at runtime will always result in an exception.

Cecil Has a Name
A: 

There is a time when I consider not using properties, and that is in writing .Net Compact Framework code. The CF JIT compiler does not perform the same optimisation as the desktop JIT compiler and does not optimise simple property accessors, so in this case adding a simple property causes a small amount of code bloat over using a public field. Usually this wouldn't be an issue, but almost always in the Compact Framework world you are up against tight memory constraints, so even tiny savings like this do count.

Steve Haigh
A: 

You shouldn't avoid using them but you should use them with qualification and care, for the reasons given by other contributors.

I once saw a property called something like Customers that internally opened an out-of-process call to a database and read the customer list. The client code had a 'for (int i to Customers.Count)' which was causing a separate call to the database on each iteration and for the access of the selected Customer. That's an egregious example that demonstrates the principle of keeping the property very light - rarely more than a internal field access.

One argument FOR using properties is that they allow you to validate the value being set. Another is that the value of of the property may be a derived value, not a single field, like TotalValue = amount * quantity.

Rob Kent