Why do we use .NET properties instead of plain old

2019-02-01 22:23发布

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.

15条回答
劳资没心,怎么记你
2楼-- · 2019-02-01 22:57

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

查看更多
男人必须洒脱
3楼-- · 2019-02-01 22:58

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"); }
查看更多
forever°为你锁心
4楼-- · 2019-02-01 22:58

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

查看更多
成全新的幸福
5楼-- · 2019-02-01 23:01

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.
查看更多
Rolldiameter
6楼-- · 2019-02-01 23:02

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++;
查看更多
贪生不怕死
7楼-- · 2019-02-01 23:03

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.

查看更多
登录 后发表回答