Suggestion added:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=178645
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âŚ
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:
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.
@[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âŚ
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.
If anyone bothers to wade through all these commentsâŚ
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.
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:
m_voltage. This breaks Microsoftâs internal style guidelines. And some people find it ugly.
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_.
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.
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âŚ)