Properties vs. Public Variables

Suggestion added:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=178645

OK, I updated the post to reflect the various comments on properties vs. variables.

If you are developing public reusable API

This is true. You should definitely consider more carefully when you’re touching a public surface area.

However, I humbly submit that the number of developers who think they’re developing a public reusable API is far greater than the number that actually are developing a public reusable API…

http://www.codinghorror.com/blog/archives/000113.html

There is a more human reason for no public members. When you’re dealing with a house full of ex-C-Programmers for whom global variables were a way of life, you have to strictly restrict public member variables in order to enforce the habit. I’ve lost count of the times I’ve let public members slide in code reviews only to sorely regret it later (just two months ago, in fact).

Also, remember that YAGNI states not to do something you won’t need, but you can incorporate practices that make the code easier to modify later, which properties do. I also practice constructor hiding for the same reason.

As far as naming conventions, I’m still torn. It is nice to be able to tell local vs argument vs member vs const, and there are just not enough casings to do this without resorting to underscore or prefix, especially if you don’t include lower case int he mix (since it is the same as camel for only one word). I generally prefix my constants with const rather than use screaming caps. Hungarian, I know, but not in a bad sense, and it maintains readability.

Jeff, are you trolling?

Can you troll your own blog?

Seriously though, with all this talk of the use of public members vs. properties (and by extension getters/setters), nobody’s brought up the subject of whether it’s even a good idea to use them.

Me, I’ve learned that unless all you’re doing is exposing a read-only property or getter on a class (a C# struct is another barrel of monkeys), there’s probably something wrong with the way that the class is designed. The problem is that when you use them, you come dangerously close to exposing implementation details. It’s a code smell, especially in public APIs, and you should consider ways of avoiding them.

Keith - But the point of properties are to clean up getter and setter methods. So you still need them however you construct your class. So yes, it’s a good idea to use them.

This may be another post of “others do it better” (especially directly following Ben’s post), but other languages do it FAR better than C#.

Point 1:

  • Some languages (e.g. Ruby) do indeed ditch the concept of public variable entirely and work ontly through properties, with helpers to easily create such properties
  • And other property-using languages (Python) make it easy to just drop in your properties when you need them (to replace your variables) without breaking the interfaces (properties and public variables being more or less seen the same way).

The issue here is that .Net considers properties and variables to be hugely different things in terms of interface and you can’t just drop-in replace one by the other one (in a word, C#'s properties are just easier-to-write-and-use getters and setters straight from Javaland), and this philosophical positioning (that properties and public variables ain’t the same thing) is further reinforced by the different coding standards (PascalCase for properties versus camelCase for members).

In a word, C#'s properties are not really properties.

Point 2:
I tend to agree, but the issue here mostly comes from C#'s dichotomy between properties and members: the interface is not uniform.

I tend to think of properties as “virtual members”, they’re members that don’t really exist “in reality” (or can be inexistant), which means that I see them as first-class members nonetheless and therefore equivalent to “real” public variables.

Point 3:
I’d use the rule that a property must never have any side effect (besides setting whatever it’s supposed to set if it has to). A getting property should be fully side-effect-less, and a setting one should only modify the data used by the corresponding getting property.

I think that properties should be able to do some heavy lifting though (as in fairly complex calculations), if efficiency issues arise because of the heavy lifting the profiler will spot them.

As a conclusion, I’ll just say that I still think of C#'s properties the way I saw them when I first discovered their existance: an incomplete, half-baked, retarded and mostly useless implementation. They don’t exist for the sake of improving the code or the abstraction level, they exist for the sake of existing and allowing someone at Microsoft to say “we have properties while Java still has all those horrible getters and setters”.

C#'s properties stink, and it’s a shame.

Lazy loads?

public string Name
{
get
{
if this.name == null
LoadName();

   return this.name;

}
}

@[ICR]: But the point of properties are to clean up getter and setter methods. So you still need them however you construct your class. So yes, it’s a good idea to use them.

Yes, I’m quite aware of what properties are for, and when you need them they’re quite useful. However, my point is that you should think twice before exposing state, whether directly through use of public instance variables, or indirectly via properties or getters/setters.

I’m a bit shocked that you are willing to crack the Pandora’s Box of public fields. I agree (with previous commenter) that this “smacks of laziness”, but I think you are also forgetting that you must lead by example. A less proficient developer may take your same reasoning and decide that all methods should be public or all parameters should be passed by reference (just in case). Repent. Repent. Repent.

“According to Microsoft’s coding guidelines, you shouldn’t prefix member variables with _ or m_ or any of that.”

And if you can find any code that Microsoft has shipped that follows those guidelines, I’ll be surprised.

btw
"However, I humbly submit that the number of developers who think they’re developing a public reusable API is far greater than the number that actually are developing a public reusable API…

a href="http://www.codinghorror.com/blog/archives/000113.html"http://www.codinghorror.com/blog/archives/000113.html"/a

That post rocks, I printed it out and put it on my office window right next to my “meetings are toxic” printout.
a href="http://static.flickr.com/68/210959102_9d9caf69b8_o.jpg"http://static.flickr.com/68/210959102_9d9caf69b8_o.jpg/a

To expand on Aaron’s remarks on Delphi:

Delphi’s property syntax is actually pretty well thought out, and very flexible (but again it was Anders H. that designed it, after all).

You implement the property in a very straightforward way:

TUser = class(TObject)
private
FUser: string;
published
property User: string read FUser write FUser;
end;

To read or write the property, use UserInstance.User.

To implement an actual getter or setter, simply change the property declaration:

TUser = class(TObject)
private
FUser: string;
procedure SetUser(Value: string);
published
property User: string read FUser write SetUser;
end;

This does not change the public binary compatibility of other code (such as in a DLL) that uses the TUser class.

As I said, it’s pretty well thought-out IMO.

Wow… Lost all my pretty code formatting. :slight_smile:

If anyone bothers to wade through all these comments…

  1. Ok, so SCREAMING_CAPS is an easy way to make constants stay out, but when do we really need it? The compiler won’t let us assign to it anyway.

  2. Public fields vs properties are context sensitive, as in frameworks vs applications. Are we writing frameworks, then properties rule! I can’t see why we should bother in an application.

But the real issue in property vs public field is about the meaningless code we have to write, not which one is better. Perhaps the better way would be to have a shorthand for the simple property and forbid variables to be public in the first place.

What were Anders thinking back then…?

You don’t need to be building a public, reusable API in order to care about binary compatibility. For any .NET object you plan to use or expect might be used in the future, it is convenient to be able to change it without recompiling everything that uses it.

Which is why, if I need to expose a field in C#, I do it with properties. It’s a great place to put NULL or boundary checks and things like that. Yes the syntax could be greatly streamlined, especially when all you need is essentially a pass-through.

But then again, if I’m exposing properties all over the place on a class that’s not strictly a “data class”, that’s when I start to think whether I should be doing things differently.

Regarding the casing thing… I use all caps for constants on a regular basis, but not in C/C++/C#. I use it in Oracle PL/SQL, which has limited IDE functionality available. With .NET and VS2005, the IDE is supremely powerful, and I find that if I really stop to think about it, the IDE (intellisense, hovering tooltips for variable types, context menues for member or argument lists, etc.) can just about always do everything for me that I used to have to do for myself with casing and prefix conventions. That said, it’s still slightly more convenient to just look at a symbol in the program than it is to move my mouse cursor over and hover on it for a second or two.

When I was in C++ on a regular basis, I used all caps with underscores for macros only. I used camel case for everything else, with a lowercase initial letter for local variables, and an uppercase initial letter for classes, functions, and the rare global. (I used to use an initial “C” for classes, but am finally breaking that habit now in C# and the dynamic languages I play with.) I used “p_” for pointers, “m_” for class data members, and IIRC, either a “c_” or just a lone letter c to denote constants. The one thing I never considered denoting were references, which are arguably a more important thing to denote than all the rest, since you often can’t tell something is a reference just by the operations being done on it.

One thing I never considered until I had PL/SQL forced upon me was using a prefix to denote arguments and their direction (pi_, po_, pio_), but that’s the “standard”, so I figured “when in Rome…” I have to admit it has been very convenient. Though I don’t know that I’d want to port that practice to other languages. Ideally I try to fit a function on one screen, so it’s not usually an issue in other languages. In PL/SQL this is more of a problem, because of the limited abstraction functionality (code tends to be verbose, with a lot of repetition), and because the embedded SQL takes up a lot of space, when it’s formatted in a readable way.

I won’t get into the “public field” vs “public property” morass, but I will say stick with public fields for Events.

public event EventHandler SomeEvent;

Gets compiled to:

public event EventHandler SomeEvent
{
add {someEvent += value;}
remove {someEvent -= value;}
}

anyways. SO unless you are doing something special, stick to event fields.

It would be nice if C# added the syntactic sugar as Kevin suggested:

public property string SomeProperty;

I would love that!

it is convenient to be able to change it without recompiling everything that uses it

I agree-- but, as others have already pointed out, the fact that replacing a public variable with a public property breaks compatibility was not a language design choice. It’s a side-effect! Along with the issues of reflection, databinding, etc.

There’s this huge, artificial divide between variables and properties that IMO should not exist.

Why are there fields and properties? This is something I have never understood. Does anyone know why this distinction exists?

I’ve tried giving up the m_ prefix but leaving it behind always seems to cause a problem. I’m wondering if you’ve got a good solution.

The problem is: suppose I need a property. (I’m doing data binding, and I also want to raise change notification events when the property changes. So I believe I have two good reasons.) But other than that, it’s a trivial property - the get accessor just returns the value.

What do you call the field? If my property is, say, Voltage, then I seem to have the following choices for the field:

  1. m_voltage. This breaks Microsoft’s internal style guidelines. And some people find it ugly.

  2. voltage or voltage. This also breaks Microsoft’s style guidelines. Some people find it ugly. (I for one find it uglier than m_voltage, because it looks like a typo.) It’s also easy to miss when reading code, and for me that seems like a showstopper. Readability is crucially important, so this just seems like a slightly worse variant of m_.

  3. voltage. This means we’re distinguishing between two members on case alone, something you recommend not doing. (A recommendation I agree with.) And Microsoft’s suggestion of prefixing with “this.” instead of using “m_” doesn’t help here because both voltage and Voltage are members. The “this.” idiom only helps you distinguish between members and locals.

  4. voltageValue, myVoltage, voltagePropertyValue, or similar compounding idiom. This is really the same solution as 1, but replacing “m_” with a different and equally arbitrary prefix or suffice. This has the disadvantage of making it unclear whether there’s meant to be a relation between the property and the field. (Although if there were a common idiom and everyone used it, that problem would be diminished.)

I think 4 has potential, but the big problem is that there’s no common idiom, and there isn’t any single obviously right way to do it. (I think I like a “PropertyValue” suffix because it makes it immediately clear what it is, and the fact that it requires a lot of typing is, for once, a good thing, because you shouldn’t ever be using the field outside of the property accessors anyhow! However, I only just thought of it, so perhaps the crushing flaw will only become obvious once I try it…)