views:

321

answers:

6

I've read some discussions about this subject, and there's something I just don't understand.

The most common answer seems to be this: use a ReadOnly Property to return cached data, use a Function to return non-cached data. Don't use a WriteOnly Property at all, cause "it doesn't make sense".

There is no performance reason for this. In IL, MyProperty exists as get_MyProperty and set_MyProperty methods. The only reason is apparently that the above answer should be assumed.

Ok, then why bother with ReadOnly Properties at all? Why not just make the variable Public instead of Private? Then why bother with Properties at all? Cached data -> Public variable, non-cached data -> Function, writing data -> Sub

Let's forget all the above, and use Properties as a handy feature? One 'item' to Get and Set data. Use common sense to know if a Get will not return cached data (possibly resulting in a delay).

-Edit- I see people more or less agree that Properties are the best option. I just couldn't understand why I found so many discussions where people were advocating against Properties.

+9  A: 

A good reason for read only properties are values that are calculated. In this case there is no variable to export.

For example

public class Person {
  private readonly DateTime _birthday;
  public int Age { get { return (DateTime.Now - _birthday).TotalYears; } }
  ...
}

In this case whether to expose _birthday as a property or a field is certainly debatable. But for other calculated values like Age, the only way to expose them as a variable is to store them in the object. In this case having an extra variable for Age is essentially storing redundant information. Exposing it as calculated property has minor overhead and avoids storing redundant data

JaredPar
+3  A: 

There is more to properties than auto properties. If you do:

public int MyProp { public get; public set; }

Then it's really no different from

public int MyProp;

But the big advantage of the former is that you can later change it to:

public int MyProp {
    get {
        // Do some processing
        return someValue;
    }

    set {
        // Do some processing
        DoMyProcess(value);
    }
}

And other code that uses your object would work without recompiling. If, instead, you had used a public field, client code would need to be recompiled if you ever want to change it from a field to a property.

Daniel Pryden
This "benefit" of properties is vastly over-emphasized, in my opinion. Sure, it is VERY important for those that are writing libraries, frameworks, etc. with a large number of "binary consumers". But for most of the .NET projects I've worked on, it was easy to "rebuild the world".
Dan
@Dan: You're right, for 90% of the projects I work on, it's no big deal as well. Like anything else, properties are a tool -- use them if they help you, ignore them if they don't. However, the reason properties are emphasized so much is the same reason why people write getters and setters in Java, or even why people write `if(0 == foo)` instead of `if(foo == 0)` -- it's a defensive coding mechanism that becomes a habit. Many would argue the habit is worth the effort. Again, if it helps you, use it.
Daniel Pryden
With C# 3's auto-implemented properties, I don't try swimming upstream here. Nevertheless, for most of my uses, a field would work just fine--and if I ever needed an explicit get/set, changing to a property would be no big deal as I would just rebuild everything. Yes, there are a few corner cases such a `ref` parameters that would break when switching from a field to a property...
Dan
+3  A: 

Properties are a convenient substitute for method-based operations. There's no functional difference between a property-getter-setter and a method that performs the same actions; in fact, if you look at IL you'll see the property accessors replaced by "get" and/or "set" methods.

The strongest reason to use properties over just allowing access to the variables is encapsulation. Let's say you're writing a library and you expose an IsBlue variable. You distribute the library, everyone loves and uses it. Now, it's time for version 2, and you want to do something when the user sets IsBlue - maybe perform a check, maybe cache something. To do that, you'll have to convert the variable into a property or method, and do the check in there. Now, you've broken all your client code - the variable they had accessed isn't there anymore. If you had implemented it originally as a property, you could have just modified the property's code, and retained binary compatibility.

Michael Petrotta
+1  A: 

"Cached data -> Public variable" - bad idea. This would allow another class to modify the cached data. Also, computing the data for caching might be expensive: using a read-only property allows you to defer calculation until the property is accessed.

itowlson
A: 

It is considered bad practice to expose your variable from your class. Plus if you change the structure of your object but keep your properties intact, it won't affect the code that use your class.

David Brunelle
+1  A: 

Reason #1 = Properties can be used in data-binding. Methods cannot.

Reason #2 = When debugging the watch window will automatically expose the properties/expand the object. Methods do not get automatically watched this way.

I remember reading someplace that the read property should not change the object state. I think that is a good practice to follow especially considering the reason #2. As soon as you watch an object and expand it in the watch the objects state could be changed thus making debugging more difficult.

Also if a expensive property is bound by accident it can introduce serious performance problems. (Attributes can "hide" properties from data binding but just making them methods means you don't have to worry about it.)

Properties are conveniences for window development. They are "used" differently in designers etc.

(I sometimes just expose some variables. But I name them as I would a property. So instead of

Integer mCounter = 0;

I just do

Integer Counter = 0;.

If I have to do "extra stuff" at some point in the future I create the Property with the same name and rename the variable to mCounter. Admittedly this is laziness on my part and I don't really recomend it. Just wrap it up in a property.)

ElGringoGrande