views:

1084

answers:

15

I understand the many benefits of providing an interface to access the members of a class indirectly. My question is: isn't that already something you can accomplish in just about any OO language using (something along the lines of)

public int NormalClass::getQuality() {
    return this->quality;
}

and

protected void NormalClass::setQuality(int q) {
    this->quality = q;
}

?

What additional benefits do .NET properties offer, beyond sheer aesthetics?

I will accept "readability" if you can make a compelling argument for it; but personally, I'm inclined to think a get/set function is more readable than a property since it is unambiguously a function as opposed to a straight-up value.

EDIT: Thanks to everybody for answering! This has been really informative for me; to sum up what I've gathered/learned from all that has been said, the following are a few conclusions I've reached so far:

  • The greatest benefits of properties come not from specific features of properties themselves, but rather from framework and IDE features which handle properties in a special way; e.g., the Properties editor, XML serialization, data binding.
  • Properties can be treated as simple values in certain convenient ways that get/set functions can't: in particular, obj.Prop++ and obj.Prop = value.
  • Properties let you get away with quick and dirty code using public members without going through the headache of implementing a bunch of get/set functions later; if you should ever need to add some logic and/or make a public member private, you can simply introduce a property and not risk breaking any old code.

Now, there is one point that's been made in 2 or 3 of the answers so far that I personally find somewhat dubious: that properties imply inexpensive read/write operations and can therefore be used in essentially the same way as simple variables. My issue with this point is that there is nothing inherent in properties that actually enforces this; it is simply how they are supposed to be used. To me, this is analogous to a "shouldBePrivate" qualifier that indicates a value should be accessed directly only by its own class, but which can still be accessed externally anyway; or a police force that patrols the streets to remind us that we should behave ourselves, but does not actually interfere when we start committing crimes (if it isn't enforced, what is it really doing for us?).

I'd be more impressed by this point if properties had some sort of built-in mechanism for ensuring read/write cheapness.

+13  A: 

Properties (specially automatic properties in .net 3.5) are more concise than setters/getters, and less lines of code == less code to maintain == less bugs.

I would say readability first, but you already said that won't count to you.. :)

Eduardo Scoz
I just read up on automatic properties: yes, point well taken there.As for regular old (pre-3.5) properties, though, how are they more concise? I am asking out of curiosity, not to be argumentative: .NET properties, as I am familiar with them, seem to require the same number of lines of code as get/set functions. But you saying this makes me suppose I may be missing something.
Dan Tao
You're right about the number of lines, I had not even noticed.. I guess I've been using auto properties for too long.. LBushkin's answer above was magnific.
Eduardo Scoz
You could theoretically put your get and set methods on different ends on the file. Properties won't let you do this. I mention this because I've came across the issue several times where code isn't logically aligned.
Will Eddins
+2  A: 

for me, it's easy:

myprop = myvalue;
console.writeline(myprop);

no need for

mysetfunc(myvalue);
console.writeline(mygetprop);

easier to remember 1 thing than 2

Fredou
there seems to be a typo at mygetprop. it should be mygetprop()
usr
let say it's speudo code and not real code ;-)
Fredou
+2  A: 

I know in some instances, you can use a property as a "Column" name like in a data set. I think .NET does this through introspection. I don't beleive this is possible with get/set functions.

LPalmer
+5  A: 

Having properties not only in the language but in the clr means that everyone on .NET can rely on their meta-data. A property has a connotation of get being without side effects and both get and set being a fast operation. Many tools use these assumption: the winforms designer, LINQ to SQL...

So it is not only about convenience but also about having an additional piece of metadata.

Here are other typical assumptions:

customer.Name = "a";
Assert.IsTrue(customer.Name == "a");

try { var ignored = customer.Name; }
catch { Assert.Fail("Exceptions are not expected"); }
usr
+10  A: 

I believe XML Serialization only reads/writes public properties, so your get and set methods would be ignored.

Also, if you have a generic list of objects, you can assign that to a DataGridView.DataSource and you'll get a column for each of your properties. That may be what @LPalmer was referring to.

Dennis Palmer
I did not know either of these things. I haven't really done any work with serialization (yet), but your second point about column generation is something that could actually come in really handy for me -- thanks!
Dan Tao
A: 

At least for DataBinding
UI-related development becomes way more complex without it.

Rinat Abdullin
+4  A: 

Two big advantages to properties:

  • They can be shown and edited in the Property Grid. Without properties, how would you know which methods to show editors for?
  • They offer a hint that something is cheap to read and write, and that reading it causes no side effects. (It's possible to violate that, of course, but by making something a property, you're declaring that that's your intent.) Therefore, the debugger can take that hint. If you hover the mouse over a property, the debugger will show its value in a tooltip. It wouldn't make sense to do the same thing for any possible method; too easy to accidentally do something with side effects.
Joe White
I like your first point. Regarding your second: I can see where you're coming from, but isn't this not an actual feature of properties but merely a convention that is encouraged? After all, .NET could provide a "WellCodedFunction" construct to encourage developers to code well, but it wouldn't actually add any real functionality.
Dan Tao
Sure, they could have made a "[FastWithNoSideEffects]" attribute to indicate "safe to show result in debugger", and then only have paid attention to it on parameterless functions with a non-void return value. But properties seem like a simpler solution.
Joe White
+3  A: 

One of the popular ways of looking at object-oriented programming is to model the classes in our programs on the concepts in our heads.

The concepts in our heads are based on the actual objects that we perceive around us (whether we perceive them or we communicate with others who have perceived them).

The objects around us - furniture, animals, space shuttles, etc. - have specific properties and act in specific ways.

That's where we get properties and methods.

In C#, a property may not be reducible to a single field-get or field-set (for example, it may require additional checks or there may be caching involved or any number of reasons). So we need a separate concept of properties with get-methods and set-methods to make our programs closer to the concepts we want them to model.

Justice
On potentially requiring additional checks, caching, etc.: yes, but this does not distinguish a property from a pair of get/set methods, does it?Conceptually, I am with you. But I also think that if this were the ONLY purpose of .NET properties, they would not be adding a whole lot to the tools available. If I have a function Box.getWidth(), I'm still modeling an object and providing a way to access one of its characteristics just as surely as if I use the property Box.Width.Of course, properties have other useful features too, as the other answers have made clear.
Dan Tao
Yes, getWidth/setWidth can model the idea of a property on an object. But they don't do it as well as a dedicated syntax for properties. The point of programming is to help us transfer our knowledge to the computer, so we design languages compatible with our way of thinking. In our way of thinking, real-world objects have properties, not getters and setters. This idea, that we think in terms of objects that have specific properties and that act in specific ways, underlies many of the other answers to your question.
Justice
+1  A: 

Maybe a minor point, but with getters /setters I find it annoying that when I'm cycling through them in an IDE with 'intellisense' there's a massive block of 'getters' next to each other and another block of 'setters'. I find it more difficult to find what I'm looking.

James Allen
+3  A: 

Properties at the essence are get/set method pairs.

Properties are a runtime supported method of exposing a pair of get set methods that have metadata support which means they are discoverable using reflection without guessing what methods are supposed to form the accessor based on method name and signature.

The other advantage of properties is that they act like fields syntactically, and not like methods, which has the advantage of creating more clean code.

I'm inclined to think a get/set function is more readable than a property since it is unambiguously a function as opposed to a straight-up value.

Most of the time properties are inlined by the Jit engine, because they are very simple, which means most of the time properties act like fields more than they act like functions, so they are closer to how fields behave than functions.

In the case of properties it doesn't mater if there is ambiguity between a function call and field access because for the greatest part you don't pay the function call cost, property getters and setters, because of their simplicity, are high candidates for inlining, which means that cost wise the are closer to fields than function calls *.

  • Note: not all properties are cheap, but the general guidelines state that they should be as simple and lightweight as possible.
Pop Catalin
+1  A: 

As usr states:

"A property has a connotation of get being without side effects and both get and set being a fast operation."

Exactly. It is implied that a getter/setter will be quick. By exposing something as property you're implying that you're quickly fetching/putting an attribute on an object. Methods are for doing some form of work assumed to involved more cycles than simply getting/setting an attribute. We usually will put a lengthy operation 'properties' into a GetFoo(...)/SetFoo(...) methods to indicate that the computation operation is heavier than a property.

Yoopergeek
A: 

They allow the user of the type to have a simplified syntax, and allow you to create read-only and write-only fields. Thus me.SetAge(34); age = me.GetAge(); becomes me.age = 34; age = me.age;

+2  A: 

Aside from the semantic correctness of using properties for a value that describes a property of an object, you can't argue with this:

obj.SetValue(obj.GetValue() + 1);

vs

obj.Value++;
JulianR
+1  A: 

With get and set methods you have to decide to use them from the start and almost always write a lot of boilerplate code for every public property your classes expose.

class Point
{
    private int x, y;

    // Ew, pointless boilerplate!
    public int  getX()      { return x;   }
    public void setX(int x) { this.x = x; }

    public int  getY()      { return y;   }
    public void setY(int y) { this.y = y; }
}

// ...

Point p = new Point();
p.setX(5);
p.setY(10);

With properties you can eliminate the boilerplate getters and setters for the 90% of properties that have only trivial getters and setters. You can just have public variables exposed directly

class Point
{
    public int x, y;
}

Point p = new Point();
p.x = 5;
p.y = 10;

Then later if you decide you want to add some behavior to your public variables you can switch them to properties with actual behavior in the get or set methods. The up side here is that users of your class are not affected at all. Nothing's changed; they don't have to switch from point.x = 5 to point.setX(5). Your public interface is stable, allowing you to use plain variables at first and switch to slower get/set methods later when you add some guarding/logging/whatever.

class Point
{
    public int x { get; set; }
}

// No change! 
Point p = new Point();
p.x = 5;
p.y = 10;

(Now strictly speaking, your syntactical interface hasn't changed, but your class's compiled interface has changed, so you do have to recompile all the code that uses your class if you switch from variables to properties. You can't get away with just recompiling your class and dropping that in place of the old class, if your class is part of a widely-used library, say. Your library's users would have to recompile their code against the new version of your library.)

John Kugelman
I like this answer a lot, especially since just recently one of my coworkers encountered this very issue (needing to add some logic to the retrieval of certain public members), and so he converted the problem variables to FUNCTIONS, which worked fine for all of the "get"-equivalent parts of the code, while breaking the handful of places where we were actually assigning values. It ended up being easy to go through and fix; but in hindsight, a property would've been the way to go. I also want to add that I am very impressed this eloquent answer was written by a monkey.
Dan Tao
+14  A: 

Jon Skeet has an excellent overview on his C# article blog about why properties matter. In it he explains why properties should be used over exposing public fields.

As for why to use properties instead of getter/setter methods, I would suggest the following thoughts:

  • Properties provide a cleaner, more concise syntax that is easy to understand and read.
  • Properties enable assignment expression chaining: A.x = B.y = C.z
  • Properties convey the semantics of data access clearly and consistently - consumers expect that there are no side effects.
  • Properties are recognized by many libraries in .NET for tasks such as XML serialization, WPF bindings, ASP.NET 2-way binding, and more.
  • Properties are recognized by the IDE and many visual designers and can be displayed in a property editor.
  • Properties enable support for the increment (++) and decrement (--) operators.
  • Properties can be easily differentiated from methods using reflection and allow dynamic consumers to extract knowledge about the data exposed by an object.
  • C# 3 supports automatic properties which helps eliminate boilerplate code.
LBushkin
I think this is the most comprehensive answer of them all. Well done.
Dan Tao
Not just ++ and --, but also the modify-assign operators like +=, *=, |=, etc.
Joe White
Wow, even when Jon Skeet isn't answer the question, Jon Skeet is answering the question:)
Oorang