Public fields and properties are not compatible
If your class wants to expose some data, you have two possibilities:
- Use a public field
public class Person { public string Name; } - Use a public property that is backed by a private field
public class Person { private string name; public string Name { get { return name; } set { name = value; } } }
The general advise is that you should not have any public fields, thus you should always use properties. However some people suggest that you can start out with a public field and that you can easily change it into a property when the need arises.
But this is not true for two reasons:
- A public field and a property are binary incompatible. When you change your public field into a property you will have to recompile all the clients of your class.
- A public field and a propery are also incompatible at source-code level. A public field can be passed as a ref- or out-parameter while a property cannot. So when you change your public field into a property, you may have to actually change the client code which may not be a trivial task.
So my advise: unless you have *very* strict performance considerations always use properties.
Regarding performance, keep in mind that a simple propery that is not marked as virtual (or that is part of a sealed class) will likely be inlined by the compiler so there shouldn't be any performance impact at all (in release-builds).
Kristof.
6 comments:
You are certainly right. But shoudln't I avoid using public fields as ref or out parameters anyway?
This would vertainly have to be checked automatically. But using the Microsoft.Cci, shoudln't it be rather simple to implement a static code analyzer that warns me if I use a public field as a ref or out parameter?
Would you accept that as a sort of compromise?
Passing a parameter as ref or out is indeed often misused (especially when its a reference type). I believe that only local variables should be passed as ref or out.
FxCop is an example of such a static code analyzer that has rules for this, see here.
What about the code design angle?
Here's my take on the matter
Cheers,
/Magnus
Kristof, good point about ref and out parameters!
So here is a question, when you need to read the values do you use the Property or internal field, especially if you are reading for a call internal for the class?
Fields and properties are also different implementations in the eyes of reflection. Refactoring a field as a property and vice-versa also requires you to refactor any reflection-related reads and writes of that property. Since reflection-implemented reads/writes are performed in a non-typesafe manner, the compiler won't catch it and you see the problem at run-time.
You also don't always have the ability to change the reflection-based code. (i.e. data-binding code in framework UI elements typically want you to specify a property or properties on the object used as it's "data-row")
Post a Comment