tags:

views:

1040

answers:

10

There's a lot of advice out there that you shouldn't expose your fields publically, and instead use trivial properties. I see it over & over.

I understand the arguments, but I don't think it's good advice in most cases.

Does anyone have an example of a time when it really mattered? When writing a trivial property made something important possible in the future (or when failing to use one got them in to real trouble)?

EDIT: The DataBinding argument is correct, but not very interesting. It's a bug in the DataBinding code that it won't accept public fields. So, we have to write properties to work around that bug, not because properties are a wise class design choice.

EDIT: To be clear, I'm looking for real-world examples, not theory. A time when it really mattered.

EDIT: The ability to set a breakpoint on the setter seems valuable. Designing my code for the debugger is unfortunate: I'd rather the debugger get smarter, but given the debugger we have, I'll take this ability. Good stuff.

+9  A: 

Part of the idea is that those properties may not be trivial in the future - if you bound external code to a field and later wanted to wrap that in a property, all of the dependent code would have to change, and you may not be able to do that, especially in the case where you are a control designer or have libraries that you can't control, etc.

Not to mention there are certain .NET practices that will not allow you to use a field - databinding particularly.

I am sure there are other good reasons as well. Why does it matter to you? Use an automatic property and be done with it. Seems like something not worth being concerned about to me...

Jason Bunting
Databinding is broken. Sucks. Guess I have to deal with taht.Automatic properties don't allow 'readonly', making immutable types a little harder.I'd like my properties to stand as saying "Watch out! This isn't just data!"
Jay Bazuzi
You can do an automatic property with a private set, which gets you part of the way there.
Gabriel Isenberg
+8  A: 

I used to think the same thing, Jay. Why use a property if it's only there to provide direct access to a private member? If you can describe it as an autoproperty, having a property at all rather than a field seemed kind of silly. Even if you ever need to change the implementation, you could always just refactor into a real property later and any dependent code would still work, right?. Well, maybe not.

You see, I've recently seen the light on trivial properties, so maybe now I can help you do the same.

What finally convinced me was the fairly obvious point (in retrospect) that properties in .Net are just syntactic sugar for getter and setter methods, and those methods have a different name from the property itself. Code in the same assembly will still work, because you have to recompile it at the same time anyway. But any code in a different assembly that links to yours will fail if you refactor a field to a property, unless it's recompiled against your new version at the same time. If it's a property from the get-go, everything is still good.

Joel Coehoorn
Can you rebuild the other assemblies? If yes, then you don't have a problem. If no, your porblem is much bigger. http://stackoverflow.com/questions/174198/c35-automatic-properties-why-not-access-the-field-directly#205567
Jay Bazuzi
If your code is a commercial class library and you make the change from public field to property, you could REALLY irritate your customers.
BlackWasp
@BlackWasp: That's the theory, but have you ever actually needed to do that? And not needed to make other breaking changes? When binary compatibility was a requirement?
Jay Bazuzi
+1  A: 

I once had fields that I wanted to expose from a windows from project which allowed the stats for the program (TotalItems and SuccessfulItems).

Later I decided to display the stats on the form and was able to add a call in the setter that updated the display when the property changed.

chills42
+10  A: 

I've had a trivial property save me a couple of times when debugging. .Net doesn't support the concept of a data break point (read or write). Occasionally when debugging a very complex scenario it was important to track read/writes to a particular property. This is easy with a property but impossible with a field.

If you're not working in a production environment, it's simple to refactor a field -> property for the purpose of debugging. Occasionally though you hit bugs that only reproduce in a production environment that is difficult to patch with a new binary. A property can save you here.

It's a fairly constrained scenario though.

JaredPar
I was just posting a similar point. I'll get you next time, Gadget.
Jeff Yates
That gave me a good laugh :)
JaredPar
+1 We've been bit by this one.
Neil Whitaker
+3  A: 

It's much easier to debug a problem involving a field if it is wrapped by a property accessor. Placing breakpoints in the accessor can quite quickly help with finding re-entrancy and other issues that otherwise might not be caught. By marshaling all access to the field through an accessor, you can ascertain exactly who is changing what and when.

Jeff Yates
+2  A: 

In .NET, from my understanding, you cannot databind to public fields; but only to properties. Thus, if you want to do databinding, you have no choice.

John Kraft
Yes, DataBinding has that bug.
Jay Bazuzi
Bug? Are you sure?
BlackWasp
For databinding, you typically also want update notification (INotifyPropertyChanged) so a property is therefore needed to raise the event.
Isak Savo
+1  A: 

Obviously, if you're not creating a shared class library, and you're not using DataBinding, then using a field will cause you no problems whatsoever.

But if you're creating a shared class library, you'd be foolish IMHO to do otherwise than follow the guidelines, for the usual three reasons:

  • consumers of your shared class library may want to use DataBinding.

  • consumers of your shared class might want binary compatibility, which is not possible if you switch from a field to a property.

  • the principal of least surprise implies you should be consistent with other shared class libraries including the .NET Framework itself.

Joe
RE: binary compatibility: I think people don't need it as much as they say, and that tirival properties aren't enough. See:http://stackoverflow.com/questions/174198/c35-automatic-properties-why-not-access-the-field-directly#205567
Jay Bazuzi
It's not just binary compatibility - it's source compatibility too.
Jon Skeet
A: 

IMHO there is no such thing as a trivial property as people have been calling them. Via the way things such as databinding work, Microsoft has implied that any bit of data that is a part of the public interface of an object should be a property. I don't think they meant it merely to be a convention like it is in some other languages where property syntax is more about convention and convenience.

A more interesting question may be: "When should I use a public field instead of a property", or "When has a public field instead of a public property saved your bacon?"

Daniel Auger
I think that Microsoft made a mistake in the Reflection APIs, making it easy to reflect over properties alone, but not over properties+fields together. That mistake has influenced the design of many other systems, and now we're stuck with it.
Jay Bazuzi
Jay, I totally understand what you are saying. I've programmed in other languages so I can see your point from a language agnostic point of view. However, this language works the way Microsoft designed it to work, not what makes sense to you or I.
Daniel Auger
+6  A: 

I'll answer your question with another one: have you ever really benefited from not making all your types and members public? I suspect I haven't directly prevented any bugs by doing so. However, I've encapsulated my types properly, only exposing what's meant to be exposed. Properties are similar - good design more than anything else. I think of properties as conceptually different from fields; they're part of the contract rather than being fundamentally part of the implementation. Thinking about them as properties rather than fields helps me to think more clearly about my design, leading to better code.

Oh, and I've benefited occasionally from not breaking source compatibility, being able to set breakpoints, log access etc.

Jon Skeet
Good response. I think I have benefitted from coding the way I do, but there's definitely room to challenge that way, and for me to improve. Unfortunately I think it's too complex to figure out in a Stack Overflow comment thread!
Jay Bazuzi
Further discourse by Jon:http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx
aleemb
+12  A: 

It may be hard to make code work in an uncertain future, but that's no excuse to be lazy. Coding a property over a field is convention and it's pragmatic. Call it defensive programming.

Other people will also complain that there's a speed issue, but the JIT'er is smart enough to make it just about as fast as exposing a public field. Fast enough that I'll never notice.

Some non-trivial things that come to mind

  1. A public field is totally public, you can not impose read-only or write-only semantics
  2. A property can have have different get versus set accessibility (e.g. public get, internal set)
  3. You can not override a field, but you can have virtual properties.
  4. Your class has no control over the public field
  5. Your class can control the property. It can limit setting to allowable range of values, flag that the state was changed, and even lazy-load the value.
  6. Reflection semantics differ. A public field is not a property.
  7. No databinding, as others point out. (It's only a bug to you. - I can understand Why .net framework designers do not support patterns they are not in favour of.)
  8. You can not put a field on an interface, but you can put a property on an interface.
  9. Your property doesn't even need to store data. You can create a facade and dispatch to a contained object.

You only type an extra 13 characters for correctness. That hardly seems like speculative generality. There is a semantic difference, and if nothing else, a property has a different semantic meaning and is far more flexible than a public field.

 public string Name { get; set; }
 public string name;

I do recall one time when first using .net I coded a few classes as just fields, and then I needed to have them as properties for some reason, and it was a complete waste of time when I could have just done it right the first time.

So what reasons do you have for not following convention? Why do you feel the need to swim upstream? What has it saved you by not doing this?

Robert Paulson
This is a great response! Most comprehensive I have found anywhere while researching the topic.
aleemb