Properties vs. Public Variables

August 7, 2006

I occasionally see code with properties like this:

private int name;

public int Name
{
    
get { return name; }
    
set { name = value; }
}

As I see it, there are three things to consider here.

  1. When is a property not a property? When it's a glorified public variable.

    Why waste everyone's time with a bunch of meaningless just-in-case wrapper code? Start with the simplest thing that works-- a public variable. You can always refactor this later into a property if it turns out additional work needs to be done when the name value is set. If you truly need a property, then use a property. Otherwise, KISS!

    Update: As many commenters have pointed out, there are valid reasons to make a trivial property, exactly as depicted above:

    • Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
    • You can't databind against a variable.
    • Changing a variable to a property is a breaking change.

    It's a shame there's so much meaningless friction between variables and properties; most of the time they do the exact same thing. Kevin Dente proposed a bit of new syntax that would give us the best of both worlds:

    public property int Name;
    

    However, if the distinction between variable and property is such an ongoing problem, I wonder if a more radical solution is in order. Couldn't we ditch variables entirely in favor of properties? Don't properties do exactly the same thing as variables, but with better granular control over visibility?

  2. Distinguishing public and private using only case is an accident waiting to happen.

    The difference between name and Name is subtle at best. I don't want to reopen the whole case sensitivity debate, but using case to distinguish between variables is borderline irresponsible programming. Use a distinction that looks and reads different: m_name, _name. Or maybe eschew prefixes altogether and use fully qualified references: this.name. I don't really care. But please, for the love of all that's holy, don't abuse us with even more meaningless case sensitivity.

  3. Is it a property or a method?

    In this case, we barely have a property. But if you are executing code in a property, make sure you've written a property and not a method. A property should do less work-- a lot less work-- than a method. Properties should be lightweight. If your property incurs significant effort, it should be refactored into an explicit method. Otherwise it's going to feel like an annoying side-effect of setting a property. And if there's any chance at all that code could spawn an hourglass, it definitely should be a method. Conversely, if you have a lot of simple, lightweight methods, maybe they ought to be expressed as properties. Just something to think about.

The really important thing to take away here is to avoid writing code that doesn't matter. And property wrappers around public variables are the very essence of meaningless code.

As for the rest, I've learned to take a "live and let live" approach to code formatting, at least for cosmetic stuff like variable names. When in doubt, try to follow the Microsoft internal coding guidelines unless you have a compelling reason not to.

But a few things still get under my skin. I've even seen .NET constants expressed in the old school all-caps way:

static const int TRIGGER_COUNT = 100;

All style guidelines aside, you know that ain't right.

Posted by Jeff Atwood
93 Comments

"All style guidelines aside, you know that ain't right."

but to add "m_" is right...

Eber Irigoyen on August 8, 2006 4:40 AM

I'm no fan of "m_", but SCREAMING_CAPS is beyond the pale.

Jeff Atwood on August 8, 2006 4:48 AM

So how do you name your constants then?
I use the SCREAMING_CAPS. But then again I'm an old mainframe hack, so it just feels right.

john on August 8, 2006 5:17 AM

I agree that the trivial property implementation of exposing a data member is a lot of code for no gain. But, I've run into several people who get religious that public members are verboten!

Nonsense. The only rational reasons I can think of to have simple getters/setters around a private member variable are:

1) to provide read-only access to a member var that cannot be declared const for some reason
2) if you're writing a component that is meant for use by some 3rd parties and there exists any chance that the component will have to be replaced without requiring a rebuild by those users (changing a public member variable to a property breaks the interface, so a rebuild is needed).

mikeb on August 8, 2006 5:23 AM

If only you could refactor a field into a property later…

Say you have 2 assemblies: MyCompany.Domain and MyCompany.UI. Domain defines a User class with a Name field. UI points to a statically compiled copy of Domain and uses User in a few places.

Time goes by and a legitimate need to refactor Name into a property arises, so Domain gets recompiled and dropped into UI and…

System.MissingFieldException: Field not found: 'MyCompany.Domain.User.Id'.

Despite the syntax similarities between accessing fields and properties, they are very different things. So if you're _ever_ going to turn Name into a property and if anyone's _ever_ going to point at your library without being able to recompile from source, you should definately use a property from the get go. It is, unfortunately, the simplest thing that will possibly work.

Jacob on August 8, 2006 5:25 AM

I think the scope matters here. I tend to wrap public fields in properties, for two reasons - one is that you can't change it later without breaking binary compatibility. Two is that you can't bind to fields. For strictly internal fields, however, I agree that just using fields is OK.

I really don't like m_, as it can be a gateway drug to hungarian, but I've learned to accept _.

I'm with you on the screaming-cap const thing. *Shudder*.


Kevin Dente on August 8, 2006 5:28 AM

And while we're on the subject…

Reflection code against fields looks very different from reflection code against properties (FieldInfo vs. PropertyInfo for starters). So even if you can recompile against the new binary, if you use reflection on that field you're hosed.

Jacob on August 8, 2006 5:30 AM

Like Kevin says, databinding doesn't work with Fields. With code snippets and tools like CodeRush or ReSharper these things are so painfully simple there's no reason not to.

Also consider this. In using an OR/M such as NHibernate and you need to populate your objects from a database, assuming you follow a Persistent-Ignorant object approach (as opposed to, say, ActiveRecord) you won't be able to set those readonly fields unless you use a readonly property. A public readonly member can not be set via reflection, so this is a big concern.

I think it's a worth-while practice to get into and it doesn't cost much ;)

Ben Scheirman on August 8, 2006 5:34 AM

As long as it is not hungarian or some variation such as Leszynski/Reddick and is consistant I am usally happy.

In Java the language recommended namining convention s uses the all caps and underscores for final variables aka constants. The reason they give is that it aids in debugging, but also has its beginning in the C days with #define.

Personally I see it kind of falling back into the hungarian problem, what if you do go and change it from a constant value to something that can change? However on the other side and the reason I do still use the all caps and underscore is that constants are special beasts and yes using a different naming convention does make them stick out, and in some instances you do get a fair amount of public constant variables and having them using a different convention makes sure you don't have conflicts.

will dieterich on August 8, 2006 5:36 AM

...and while we're on the subject of naming practices...

I agree that a variable called strName is kind of stupid and pointless.

But what about ASP.NET controls on a page (or winforms) ? I whole-heartedly agree with naming textboxes like txtName or lblMessage, dgCustomers, etc. This is a good way to distinguish local private members from page controls.

The reason I bring it up is because on my current project all of the control names match up with database columns (shudder) and they use a large series of helper methods to make crud forms easy to bind to. (so txtFirstName becomes FirstName)

Ben Scheirman on August 8, 2006 5:37 AM

One other thing - I do wish Microsoft would let us write:

public property int Name;

Which would let us expand a trivial property declaration into a real property get/set without breaking compatiblity. Maybe some day.

Hey, wait a sec...why in god's name does your sample use "int" as the data type for a name? ;)

Kevin Dente on August 8, 2006 5:40 AM

On issue with dotnet is that during databinding only properties are seen. Public member variables are not. So any object that you might bind to a a GridView or the like must be a property.

The other nice thing in dotnet 2.0 is the ability to set access control on the get or set. So sometimes I end up doing this:

public int Name
{
get { return _Name; }
internal set { _Name = value; }
}

You can't do this with a variable.

Brett on August 8, 2006 5:42 AM

My given name is 75012, but my friends call me "Jeff".

Jeff Atwood on August 8, 2006 5:43 AM

However on the other side and the reason I do still use the all caps and underscore

Less code? That's a worthwhile cause deserving of serious discussion.

But whether you call something "foo", "Foo", "_foo", or "FOO"? Meh.

Naming conventions are highly controversial and religious. Developers should pick something they like, something that's hopefully not too much at odds with the "local conventions", and just go with it. A lot of discussion and hand-wringing over naming isn't worthwhile.

That said, I think ALL CAPS IS REALLY HARD TO READ!

Jeff Atwood on August 8, 2006 5:48 AM

I think the all caps makes sense. It's a quick way to determine that the value is in fact a Const. It's not a 'variable' that is being set or is changing elsewhere. To a developer who has to support my code, they simply see the all caps and can immediately determine that this is in fact a hard-coded value.

Brian on August 8, 2006 5:55 AM

I'm a huge fan of always wrapping my fields with properties.....it just feels right.

To me the effort in wrapping is minimal (having a macro that creates either readonly or normal properties for the selected fields helps). When I see code that just has a mixture of public fields and properties IMHO it smacks of laziness.

But I agree with the earlier comment about context. I mostlt develop domain layer code....so my classes generally fall into three categories: services, entities and value objects. I like all my value objects to be immutable (which properties help with), my O/RM likes entities to have properties, and my service classes generally don't need properties.

At our company we don't use hungarian (except maybe in web apps) but we do use scope prefixes: m_, p_ and s_ (s_ is for static fields, and p_ is for parameters).

When I was first introduced to p_ for parameters i HATED it, but my project lead at the time said that the feeling would pass after two days...and it did. I use it all the time now and find it incredibly useful. It's kindof hard to explain but I don't know anyone who's tried it for a couple days who doesn't then go on to use it all the time.

Andrew Davey on August 8, 2006 6:00 AM

p_ is for parameters

Ick! Ack! Uck! (Run screaming).

I have no problem with local coding style variations, but something that makes my code looks dramatically different from virtually all the rest of the .NET code "out there"? No thanks.

Observing the conventions of the framework is my number one rule.

Kevin Dente on August 8, 2006 6:06 AM

Holy fark. The advice on fields vs. properties is totally wrong, wrong, wrong, wrong, wrong.

I suggest, no, insist, you read Effective C#: http://www.amazon.com/gp/product/0321245660/sr=8-1/qid=1155081911/ref=pd_bbs_1/002-4539717-3298461?ie=UTF8.

If you think it's "difficult" to write all those getters and setters, here's a free VS plugin to create them:

http://www.adersoftware.com/index.cfm?page=vsPropertyGenerator2

foobar on August 8, 2006 6:07 AM

Clearly there's a lot of friction in the seemingly minor distinction between a property and a variable. A coworker and I were just discussing this. Here's a idea he had:

Why not do away with variables in favor of properties?

That's one Gordian Knot-esque way to reduce the friction. And why not? How are variables really adding value? Don't properties do exactly the same thing, but with better granular control over visibility?

Also, I really like Kevin Dente's idea:

public property int Name;

Paging Anders Hejlsberg..

Jeff Atwood on August 8, 2006 6:09 AM

Chalk me up for constants with all capitals. Most people know that all caps is a constant and it makes sense to see them that way.

To me, it just screams YOU_CANT_CHANGE_ME_IM_IMPORTANT and I like it that way.

If you need to refactor to an instance variable it helps, because you can search for the caps version and replace with the instance var of the same name in camelCase or whatever.

It also helps when using code completion in your IDE, as you can just scroll to the capitalised constants to get what you are looking for.

I don't see a better way of doing this. I'm curious, what do you use instead of caps?

Sam on August 8, 2006 6:20 AM

public property int Name;

The last few weeks I have really been thinking about that for VB. Maybe...

Public Auto Property Name as Integer

I think Auto is still a keyword.

I also want a way to expose some methods of an internal object without exposing them all.

Private m_myList as ArrayList

Public Function Count as Integer Exposes m_myList.Count

Jonathan Allen on August 8, 2006 6:39 AM

Jeff, you still haven't said how *you* declare your constants. I, too, use SCREAMING_CAPS. I agree with Brian and Sam -- it's a great way to set the constant apart from your other variables. You can quickly tell that a value is a constant.

jdkludge on August 8, 2006 8:00 AM

To any C++ (or C programmer for that matter) the all caps conventionn is only for macro definitions. No code that survives through the pre-processing stage should use it.

As far as C# is a descendant of C/C++ I would expect it to follow their conventions.

A while I ago I wrote about how to get public variables to feel like accessors in C++. I don't know if it can be used in languages like C# - I have no idea what the template support is like. Anyway the article is here:

http://www.kirit.com/C%2B%2B%20killed%20the%20get%20%26%20set%20accessors

Kirit on August 8, 2006 8:46 AM

Jeff,

I'm going to have to disagree with you here. If you are developing public reusable API, then you should use properties for the following reasons:

- Not all binding works with fields
- You can't apply CAS attributes to fields
- Harder to debug (ie can't set breakpoints on fields)
- It's a breaking change to turn a field into a property
- Obviously you can't do validation

We actually have an FxCop rule (DoNotDeclareVisibleInstanceFields) that checks for visible fields.

By-the-way not all of Microsoft (let alone DevDiv) uses the Microsoft internal coding guidelines. Each individual team is free to choose their own style guidelines.

Regards

David

David M. Kean on August 8, 2006 8:58 AM

So Jeff, how do you write your consts? You hate ALL CAPS, OK we got it. :)

Diego on August 8, 2006 9:02 AM

So it looks like the benifits of wrapping fields with properties wins out. Next!

Diego on August 8, 2006 9:03 AM

Not to beat a dead horse, but mocking a public data member is pretty difficult...

(That's mocking as in unit testing using mock objects, just to clarify.)

Michael on August 8, 2006 9:22 AM

Honestly Jeff, you really just want to morph C# into Ruby.

"Also, I really like Kevin Dente's idea:

public property int Name;"


attr :Name, true

Scott on August 8, 2006 9:39 AM

"That said, I think ALL CAPS IS REALLY HARD TO READ!"

For anything particularly long (several words, a whole sentance, etc - sure. For something relatively short it's ok, imo.

eg:

static int MAXTHREADS = 4; // Ok
static int MAXCUSTOMERDISCOUNTINDOLLARS = 50; // Annoying..

(excuse me if the syntax is wrong, I'm a VB.NET guy)

In VB.NET you don't have case sensitivity, so "MAXTHREADS" vs "MaxThreads" vs "maxThreads" is all the same (Intellisense will auto-correct the case to the same as where it is defined, however).

Private variables should be prefixed with an underscore if you're going to have a method or property of the same name.

Eg:

Public Class Customer
Private _Name as String

Public Property Name as String
Get
Return _Name
End Get
Set(ByVal Value as String)
_Name = Value
End Set
End Property
End Class

Will on August 8, 2006 10:15 AM

I have to say, on point 1, you're very mistaken. It's absolutely essential in libraries for binary compatibility, replaceability and servicing reasons to always expose private fields as properties, and never as public fields - not to mention the uniformity benefits of depending on reflection and making the assumption that only properties matter.

What's more, fields can be passed as ref or out arguments, whereas properties can't - so that refactoring can easily break code. It's more essential in libraries, of course, where you have a strong business case not to break other people's code.

(Also, I notice you've got something against me hosting my blog on Bl*gSp*t - that's not very nice. Not a problem though, since I've got some domains too :)

Barry Kelly on August 8, 2006 10:41 AM

I have to disagree with Jeff.
SCREAMINGCAPS are hard to read, true.
SCREAMINGCAPSTHATAREEVENLONGER are even worse.
But having a const value shine from the code is a timesaver and sometimes, a lifesaver.
Here (at work) we use SCREAMING_CAPS_WITH_UNDERSCORES and the code looks just fine. Seeing all these i18n consts and no string consts let you know you've done the work correctly (at least from that aspect). Searching for that elusive place where the code gets called is easier, since you've got a related string (an I18N const) highlighted and... well, screaming. I've been programming "alone" for quite some time and working at it for a bit (though I wouldn't consider myself a junior programmer) and I've always (at least since I started paying attention to coding style) used caps for consts. always. So, like some said, it feels "right" to me.

Ran on August 8, 2006 11:08 AM

The framework provides a pretty clear example for how to name public constants - Pascal case. For example, Int32.MaxValue.

Kevin Dente on August 8, 2006 11:46 AM

Much as I'd love to ditch Hungarian and ALL_CAPS conventions, as a consultant I'm always handed the yellowed, rusty-paper-clip-stained "standards" document that one overambitous employee wrote to coincide with the release of Visual Studio 6 SP5....

Jeff on August 8, 2006 11:47 AM

Exposing public fields is only ok when you will always control all of the code that references them, it will always be ok to update all of that code when you need to change the type/name, and you will always recompile and redeploy all of that code at the same time.

Or, said another way, it's a lazy tradeoff that lets you avoid a completely trivial amount of work in favor of a potential "holy hell we're screwed" problem later. That's not the sort of tradeoff a professional would make - once they've been bitten by it and have spent time thinking about the tradeoffs they're unconsciously making.

chrisbro on August 8, 2006 11:52 AM

I do use "SCREAMING_CAPS" for constants.
However, one way to distinguish them is to prefix it with c

for e.g. const int cMaxThreads = 10;

Kalpesh on August 8, 2006 12:38 PM

If I remember correctly, you also can't use the intellisence help things with fields in Visual Studio, only properties.

[ICR] on August 8, 2006 12:42 PM

C'mon, what happened to the fundamentals of object-oriented design? State, behaviour, identity??

Preferences when coding are always a topic of disagreement, but seriously .NET provides such a clean class and object design, so you must do it justice and follow the naming conventions outlined in the SDK.

Public variables? No, no, no! Bad, bad, monkey. Objects should maintain state and behaviour, and should not allow random access to their state variables.

Naming collisions when variables and properties differ only by case? Well that's bad naming as not all languages are case sensitive - it's not CLS compliant.

Tom on August 9, 2006 2:23 AM


I *like* to name constants using SCREAMING_CAPS_WITH_UNDERSCORES.

Eric Sink on August 9, 2006 3:07 AM

A_CONSTANT_ByAnyOtherCaps_SCREAMS_justassweet

Ian Johns on August 9, 2006 3:23 AM

Suggestion added:

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

Thomas Eyde on August 9, 2006 3:25 AM

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

Jeff Atwood on August 9, 2006 3:55 AM

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.

John Woodard on August 9, 2006 4:30 AM

Jeff, are you trolling?

Raoul Duke on August 9, 2006 4:34 AM

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 Gaughan on August 9, 2006 5:59 AM

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.

[ICR] on August 9, 2006 6:05 AM

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.

Masklinn on August 9, 2006 6:57 AM

Lazy loads?

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

return this.name;
}
}

Seth Davies on August 9, 2006 7:26 AM

@[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.

Keith Gaughan on August 9, 2006 7:47 AM

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.

Matt on August 9, 2006 8:02 AM

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

Scott on August 9, 2006 8:12 AM

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

Scott on August 9, 2006 9:07 AM

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.

KenW on August 9, 2006 9:16 AM

Wow... Lost all my pretty code formatting. :-)

KenW on August 9, 2006 9:16 AM

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

Thomas Eyde on August 9, 2006 9:34 AM

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.

WaterBreath on August 9, 2006 9:43 AM

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!

Haacked on August 9, 2006 12:47 PM

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.

Jeff Atwood on August 9, 2006 12:52 PM

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

Terrier on August 9, 2006 1:49 PM

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

Ian Griffiths on August 10, 2006 2:34 AM

Just checked this in the "Framework Design Guidelines", and it says "no public or protected instance fields". It then notes:
- Trivial properties can often be inlined by the JITer (so no performance overhead)
- Cannot change fields to properties without breaking the interface (whether used directly, or via reflection).

While these are aimed at framework developers, it would seem there is little loss (especially since VS2k5 will do the property generation for you), and several benefits in always using properties.

Richard on August 10, 2006 7:50 AM

WTF?

"public property string IOnlyWriteTrivialObjects"?

Developer: So, how do you create a property in C#?

ADDGuru: Well, you use "public property string memberVariable"

Developer: So what does that do?

ADDGuru: Well, it allows you to get and set a variable.

Developer: So what if you just want a setter or just a getter?

ADDGuru: Um, well, you use a whole other syntax. That maybe you should have used in the first place so that you could make these changes easily.

Developer: How about if I want to add some logic to the getter/setters?

ADDGuru: Um, well, you use a whole other syntax. That maybe you should have used in the first place so that you could make these changes easily.

Developer: Oh, I see. So that first syntax is pretty well useless.

ADDGuru: Yup.

foobar on August 10, 2006 8:24 AM

WTF #2

Am I the only person here who actually creates business domain specific types, and actually sometimes needs only getters? Am I the only person who uses private variables?

"What's the difference between a variable and a property?"

What the hell? Were you smoking crack when you wrote this, or have you literally never created a type that needed private variables? Or even a trivial bit of logic in a property? I know you've written about how OO design is so "hard", and how you prefer DataSets (shudder), but my God.

foobar on August 10, 2006 8:29 AM

public property string IOnlyWriteTrivialObjects"

In case you missed the last 50 comments, we need this because .NET has a crazy, nonsensical division between variables and properties. I'll recap for you:

a) You can't reflect on them the same way
b) Changing from variable to property (or vice-versa) breaks binary compatibility
c) You can only databind to a property

have you literally never created a type that needed private variables?

Have you literally never created a type that needed private properties?

I know you've written about how OO design is so "hard"

Not so much "hard" as "frequently abused".

Jeff Atwood on August 10, 2006 10:34 AM

"While these are aimed at framework developers, it would seem there is little loss (especially since VS2k5 will do the property generation for you), and several benefits in always using properties."

I don't think runtime performance or automation was ever the issue. But readability is.

Thomas Eyde on August 10, 2006 10:58 AM

How can a guru (as inn ADDGuru) so miserably interpret these posts to promote three syntaxes?

To the guru, which fails to earn the title, we'd like two property syntaxes:

1. The old one. Use this when syntax #2 is not up to it.
2. A one liner to create the simple, passthrough property which happens to be used a lot.

We could extend the syntax a little:

public readonly property int Number;
public writeonly property int Number;

But the latter would be just cosmetic. If we can write to the property, what's the harm to be able to read it?

Thomas Eyde on August 13, 2006 2:56 AM

some notes...

- no good reason not to use a mutator/accessor...keeping it simple in my mind means being as consistent as possible. That prevents you from giving any thought to using get/set methods, or not.
- performance should not be a concern...simple mutator/accessors should be inlined. Of course, there are exceptions and other kinds of conventions like in C unix programming with structs.
- as a matter of style, using getters and setters and avoiding local variables is also a way of making things very clean and minimizing mistakes.
- I don't think adding "m_" is always right these days. Use an IDE with proper semantic highlighting. =)

sak on August 13, 2006 6:41 AM

ok, let me add something...

properties/public variables should be fine as long as it is not an externally-facing struct...

used internally a public-variable-struct object is very nice...

sak on August 13, 2006 6:50 AM

On naming standards, I learnt C# on the back of the VS2005 beta - which meant I got to see the updated FxCop in there, which means I learnt that:

int importantData; // was the field
and
public int ImportantData {...} // was the property

so all this _importantData stuff seemed fairly turgid to me when I first saw it. And, I am another one who uses all-caps'n'underscores for consts.

It seemed to me that the _intention_ behind some of the MS naming standards was accounting for the fact that the dev environment allowed for much visual feedback on what something was, whereas in the days of C we had our monochrome text editors and that was it.

I'm therefore a little surprised that no-one seems to have said:
"I want my constants to be simply RED, and I want my static readonly's to be DEEP PURPLE, lest I forget I can not assign to them"
Don't most people code .Net in IDE's that understand the context (as opposed to text editors that can only do simple syntax colouring?)

Whichever way, part of the purpose of a naming standard is to help you read and understand the code; we tend to give constants a different naming scheme so that we can SEE and FEEL they are constants; the fact the compiler won't let us assign to them is irrelevant, we need to understand this before that stage.

Nij

Nij on August 14, 2006 4:32 AM

screaming constants help me know quickly what is a constant -- and all I'm looking for here is less head scratching while coding.

"Name" and "name" coders need to be electrocuted or something. But in their defense it's not all their fault, but rather those who invented case sensitive languages.

Coding a public variable as a property, while overkill many times, at least gives you the choice of later adding some intelligence or safety net logic to the value returned (for example) while not breaking anything.

Steve on August 17, 2006 10:55 AM

My preferred coding style is:

const int _DefaultName = "John";
int _name;

public int Name
{
get { return _name; }
set { _name = value; }
}

This bumps all of the class members to the top of the autocomplete list, and makes it easy to distinguish between properties, variables and consts without resorting to ALLCAPS or too many extra characters.

Ilya Haykinson on August 20, 2006 1:18 PM

I think we can safely conclude when it comes to naming conventions, there is no right and wrong. I don't personally see the added value using UPPER_CASING, but again, it could be that I am just not used it.

I proposed a feature request to Microsoft: To move the instance field inside of the property block. The intention is to secure all code to use the property, also the instance itself. There are some circumstances where accessing the field would be wrong: Like lazy loaded properties.

But that is only a small step from treating the property as a first class object. Our getters and setters would then be overrides on that object. No getter and setter means we use the default implementation, which is the proposed shorthand definition.

Thomas Eyde on August 21, 2006 4:18 AM

Irregardless of the need for properties in winforms, classes still should not fully expose themselves. Properties allow for classes to provide information, but keep its inner workings secretive.

Writing wrapper code for a "just in case" scenario is not an option. I just do it. Bolt-on's may be added later in the project, and the time for adding the bolt-on is usualy far less the time available for writing the initial framework code. Time lines change, and you can't always just KISS until you're biting the bullet on time and adding that functionality in the future.

Brian Pina on September 14, 2006 10:14 AM

I don't want to be a dead horse (but I will):

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

This is not true. No Microsoft guidelines recommend this. The Framework Design Guidelines* only talk about public API (there are no naming guidelines for member fields - as we have guidelines that state these shouldn't be public).

* The internal 'Microsoft' guidelines were published in the book. However, these are neither official, nor used by most of the teams in Microsoft.


David M. Kean on October 19, 2006 9:27 AM

LOL...I meant to actually say 'I don't want to beat a dead horse'.

David M. Kean on October 19, 2006 9:28 AM

Here's another example of the friction between property vs. public variable. This time the examples are Java and Ruby.

http://blog.grayproductions.net/articles/2006/03/10/java-a-bit-on-the-wordy-side

Jeff Atwood on November 23, 2006 3:23 AM

Have you ever had to locate where and when a Property is being set in an appliccation when the property name is something very common to your application? A search on the word gets you 100 times the amount of hits. The logical thing to do would be to put a break point on the property. However, when your property is a public variable, you won't be able to do that, at least not in VB. This is my strongest argument against public variables.

J Reddy on February 18, 2007 5:06 AM

The difference between a field and a property is essentially that a field is a place to store some data, where a property is a means to access some data. This may sound a little puristic, but I think separating the concepts of storage and access is important.

To make my point clearer:

class Sphere{
private float _radius;

public float Radius{
get{
return _radius;
}
set{
if( value = 0.0 ){ // sanity check for value
_radius = value;
}
else{
throw new ArgumentException();
}
}
} // property Radius

public float SurfaceArea{
get{
return 4*Math.Pow(Radius,2)*Math.PI;
}
} // property SurfaceArea

public float Volume{
get{
return 4*Math.Pow(Radius,3)*Math.PI/3.0;
}
} // property Volume

public float Diameter{
get{
return 2*Radius;
}
} // property Diameter

} // class Sphere

Also note that for the calculated properties, I do not access _radius directly, but use the public property Radius. In this case, it is highly improbable that the implementation of Radius may change, but you may at some point opt to store the diameter instead of the radius and calculate Radius instead.
In short, properties are an interface to data, while fields are storage locations. Declare your interface and use it: access the storage locations only through their interface.

Martin Schwarzbauer on April 11, 2007 3:40 AM

Heh, just found this site... I was wondering what ppl thought about predominantly simple properties without any logic going on and I have become pretty much standardized in any public variable becoming a property. Plus, databinding is a given. But other than that...

one, it's consistent. two, control when/if you need it. three, maintainability/expandability.

oh, and if it gets too long for ya and you don't like scrolling it, just #region it. Too easy. And then you are done, and can start working on the more interesting stuff.

BTW, I use caps for props. ha, sorry, I just like it more. Looks clean. I'm Keeping It Simple Stupid, imho. :)

neato on April 12, 2007 2:42 AM

Does anyone else avoid constants in favour of app.config Settings when appropriate? Similar to static readonly objects (promoted in Effective C#), using app settings can be changed without rebuilding (the values aren't being inlined), and if you want to document those settings within the class structure you can wrap them in static properties (though if you don't like the loose relationship with settings and classes you can just use the default settings wrapper, it just takes longer to write out):

/// summary/
public static object AppSettingValue
{
get { return Properties.Settings.Default.AppSettingValue } ;
}

Daniel Crenna on June 21, 2007 2:03 AM

I came to this page looking for THE final solution to this problem. I quickly went through the comments and I think Ian Griffiths is into something.

I cannot decide: a suffix, or maybe still a prefix. I think it must be short (dont like PropertyValue much). Maybe "value", perhaps "internal", "inner", "hidden", "field", "store", "holder", "keeper"... "state"... "innerState"?

Not 100% satisfied with any, but I guess I will go with "value" or "state". Perhaps someday an idiom will be stablished.

Diego on June 25, 2007 1:16 PM

I have just found this paper by Robert Martin:

http://www.objectmentor.com/resources/articles/lsp.pdf

He uses an "its" prefix for private fields holding property values. The examples are in C++ so there are not actual properties, but read/write accesors.

I wanted to revisit this post because I think this prefix is very close to being the one. The only doubt that remains is that perhaps Ian is right and having a longer prefix/suffix is a good thing.

Diego on August 23, 2007 3:23 AM

@Jeff Atwood :

I think the static const int TRIGGER_COUNT = 100; should read const int TRIGGER_COUNT = 100;

Andrei Rinea on August 30, 2008 9:09 AM

Start with the simplest thing that works-- a public variable. You can always refactor this later into a property

Yes, but then you've got a mix of public fields and properties, which has the following problems:

- A little harder to debug since you have to look in a couple places potentially

- A lot harder to regenerate your class if you're using code generation

- A little harder to explain your system when another developer starts working on the project

Joel Hendrickson on February 6, 2010 9:51 PM

Yeah, I gotta say I usually go with screaming caps. I don't like to use scope prefixes, but I usually do like to use constants. Over time I usually promote them to command line arguments or configuration settings and change the case at that time. I agree that it's nice to glance at a function and see what's being set at compile time.

Jon Galloway on February 6, 2010 9:51 PM

Obligatory "Ruby does this right" post. Hardly needs to be said by this point- we can pretty much assume that if you're being irritated by a feature of the .net languages a quick check of the Ruby docs will show a way in which the problem has been solved...

Ben Moxon on February 6, 2010 9:51 PM

According to Microsoft's coding guidelines, you shouldn't prefix member variables with _ or m_ or any of that. So you have three choices if you follow that guideline:
1) Don't wrap with properties, just use public fields;
2) Use camelCaps for the member variable and PascalCaps for the property (Microsoft's recommendation); or
3) Create two distinct names for every single field.

No developer is going to waste time on #3, and since VB.NET doesn't allow #2, and since your experience has largely been with VB (I don't mean that negatively, honestly), it explains why you advocate either #1 or the MS-disapproved member prefix.

I eschew the exploitation of case sensitivity most of the time, but it actually kind of makes for field-accessor properties. A maintenance coder does not even need to search for the property declaration to know that, yes, the property is really just a wrapper for some member variable. Unless it isn't just a wrapper, in which case the naming is totally wrong. And obviously this isn't a valid convention in VB or other case-insensitive languages.

I think it would be a great idea to be able to use a "property" syntax. Delphi actually has this syntax although it's not quite the same thing:

SomeProp: Integer read FSomeProp write SetSomeProp;

Where "FSomeProp" is the field name according to Delphi's naming conventions and SetMyProp is a method. The "write" doesn't have to be a method, it could also be FSomeProp. The beauty of this is that you don't actually have to make the stupid "getter" and "setter" methods - you can link both assignments directly to the member variable, which means only one extra line of code. And you don't even need to write that code - just write the property and Delphi's class completion will insert the member variable.

As an aside, Delphi (Pascal) is *not* case sensitive, hence the "F" prefix. I'm not for or against case sensitivity, I'll use whichever conventions are accepted for the language I'm using at the time.

It's not perfect but it is a lot less clunky than C#, and I think they really need a better property syntax. It would be especially nice not to have any extra code at all and declare a property/field hybrid like Kevin's. C# already has this syntax for Events, so why the hell not Properties? Although I'm not sure if it makes sense to completely ditch fields in favour of properties because properties can be non-trivial overhead, and private member data is the most likely data to be used in long loops. People will argue that it's trivial overhead but it's also a trivial productivity boost - is it really worth the trade?

As for the distinction between local and member variables, it was a bit of a pain at first, but I've taken to using the "this" reference. It just makes sense, especially in constructors where you are literally initializing the member variables through parameters, and thus the parameters ought to have the same names as the member variables so - once again - anybody who reads the constructor can figure out what's going on.

I think my reply was longer than the original post. Oh well, we *are* talking about verbosity here! :-)

Aaron G on February 6, 2010 9:51 PM

Has anyone suggested the "property" keyword to the C# team? It is, as Haacked pointed out, merely syntactic sugar, so I don't imagine it would be too hard for them to implement. And since it already sort of exists in Delphi, which was Hejlsberg's brainchild, it stands to reason that he already knows what's involved.

With all the craziness they're adding to the new version like Linq, anonymous types and so on, this one ought to be a no-brainer.

Aaron G on February 6, 2010 9:51 PM

"Why waste everyone's time with a bunch of meaningless just-in-case wrapper code?"
think of an extreme case. you have a data transaction object that represents a person, and is used in 60,000 places in your enterprise application. The client has just requested that all first name attributes have to have the first letter capitalized, and the middle name abbreviated to one letter. Now if the dto had public accessors, you would have to change the format of these attributes in 60,000 places. But if you encapsulated the attributes you would only have to change one line of code in the dto person class.

jason on February 6, 2010 9:51 PM

I know consts are what we're "supposed" to do, but I bl**dy hate them and the way they're done here's an example of piece of javascript code i was looking at tonight

dialogHtml = dialogHtml
.replaceAll(WYM_BASE_PATH, this._options.basePath)
.replaceAll(WYM_CSS_PATH, this._options.cssPath)
.replaceAll(WYM_WYM_PATH, this._options.wymPath)
.replaceAll(WYM_JQUERY_PATH, this._options.jQueryPath)
.replaceAll(WYM_DIALOG_TITLE, this.encloseString(sType))
.replaceAll(WYM_DIALOG_BODY, sBodyHtml)
.replaceAll(WYM_INDEX, this._index);

What hell does that mean? To work out whats going on here, i've got to hunt down the CONSTs and the _options and then get back here to piece it all togehter, nightmare! There's got to be a better solution than this, this is nasty. Using consts in Javascript is particullary bad as there is very limited support for intellisense in js IDE's(that i know of) but a lot of people do it. Anyone got a better solution? As for properties, check out .net 3.5 auto-properties, ooh yeh!
public class Customer{
public int CustomerID { get; set; }
public string CompanyName { get; set; }
public Address BusinessAddress { get; set; }
public string Phone { get; set; }
}

simon on February 6, 2010 9:51 PM

In my previous job we used to use these naming conventions:

public class Employer
{
private static int ourEmployeesCount; // static - our
private string myName; // fields - my
private int myAge;

public string Name
{ get { return myName; } }

public int Age
{ get { return myAge; } }

public Employer(string theName, int theDateOfBirth) // params - the
{
int anAge = DateTime.Today.Year - theDateOfBirth; // local variable - a, an

myName = theName;
myAge = anAge;
ourEmployeesCount++;
}
}

Just my 5 cents :)

Coroner Coroner on July 2, 2010 7:52 AM

Property always a better choice instead of public variables.Property is safe while public variables are unsafe. And you can not debug with public variables but you can do that with property.

For more detail please see
http://interview-preparation-for-you.blogspot.com/2010/12/why-property-is-better-choice-instead.html

Khaleek Ahmad on December 28, 2010 10:41 PM

coding standard's are always said to be enforced no matter whether you are writing bash script using parameters or java program using classes, yet people don't follow them why ?? could be many reason but foremost reason is awareness, laziness and simply don't care attitude. but until coder is consistent with existing code lines I would let them go with fancy coding practice.

Javabuddy on June 27, 2011 5:22 AM

The comments to this entry are closed.