Partager via


Is it a field or a property?

I very much value code reviews, as long time readers can attest.  During these reviews, I have often found myself wondering whether a given line references a field or a property.  When reading isolated portions of code, properties can be easily mistaken for fields. 

Player player = new Player("Someone");String name = player.Name;player.Age = 22;

By looking at only the two lines above, is it possible to tell, conclusively, whether or not Name and Age are properties or fields on the Player object?  I assert that it is not.  Let's take a closer look at fields and properties.

A field is a variable exposed by the object.

public class Player{    public String Name;     public Int32 Age;}

Properties are methods (a getter and/or a setter).

public class Player{    private String m_Name;    public String Name    {       get{ return this.m_Name; }    }    private Int32 m_Age;    public Int32 Age    {        get{ return this.m_Age; }        set        {           if( 18 >= value )           {               throw new ArgumentException("Player must be at least 18 years old.");           }           this.m_Age = value;        }    }}

Each of the above examples would allow for code that looks like the original client snippet.

I typically use properties, in part, because they provide my client code with the same easy to use syntax for setting and retrieving values from a class that I get from fields with the added benefit of data validation when setting the value.

Take care,
-- DK

[Edit: fix error in example]
[Edit: add "m_" to private class members]

Disclaimers:
This posting is provided "AS IS" with no warranties, and confers no rights.

Comments

  • Anonymous
    October 13, 2006
    One out of thread question is - would you use a business layer or a domain layer at all in a Compact framework application , considering the devices have small RAM sizes ? Will object creations not eat up that memory fast ?

  • Anonymous
    October 15, 2006
    I don't think it is a good if identifiers only differ by case, like name and Name (even though "name" is not public). Better would be to prefix the private variable with an underscore, it will also help telling it apart from private variables that do not represent a public property. David Kline: Excellent point.  Especially important when working with case-insensitive languages.  I've updated the examples to use a traditional (C++) "m_". Even though from a source code point of view there is no difference between a field and a property, in general it is best to never use a public field, but always use a public property, even if you're just doing this: get { return _name; } set { _name = value; } If you were to use a public field in an assembly that you're shipping, and then need to add initalization or validation later, changing the field to a property will break binary compatibility, because as you mentioned, setters are getters are methods. A client program that was compiled against the old assembly with public field will break with the new assembly where this field was changed in to a property. By using public properties from the start, you prevent this problem from happening.

  • Anonymous
    October 15, 2006
    I guess it all comes down to culture and current practices at the company where the code is written. With proper capsulation only properties should be exposed, not fields. If we knew that this was the case, or supposed to be the case, we would expect properties. The code review of the refered class would catch any deviation from this practice, i.e. a sloppy programmer who made a field public instead of wrapping it as a property. I advocate capsulation but must admit that I sometimes take short cuts when the value exposed doesn't affect behaviour. I am getting better at not exposing fields though.

  • Anonymous
    November 01, 2006
    Having Public fields on a class is deemed bad practice.  Its effectively creating global variables", a practice that has been frowned upon since the advent of O-O (see McConnell's books!) In respect of the prefixes "m_" - whilst this might have been a C++ practice there seems little point in having two characters.  What I've generally seen in practice is: a) underscore only, e.g. _name,  as used in the official Microsoft CB course curriculum b) mName, as used in the Wrox books. Whatever standard is adopted doesn't really matter, as long as one is consistent in its use.  I struck a bad example of the case sensitivity in a Microsoft MSDN article this morning  where a variable of type "Image" was declared as "image", and further down a property was also declared as "Image", or something similar.  I had decided to convert the code to VB .Net as it was written in C# (no surprise from the above since C# is case sensitive.  It should have been an easy exercise to convert but it wasn't because of the Author's naming conventions (or rather lack of!)

  • Anonymous
    November 29, 2006
    My comment is does it matter, if you're reading code, whether it accesses a class's property or a field? It should, by default, access a property for all the obvious reasons. During the code review of the class itself is the time to make sure that the class exposes no public fields.

    David Kline: True, in the case where you own the class as well as the client code.  If you do not own the class code, it's important to know the difference since properties are method calls and may throw an exception, while a field access likely will not (unless the object has been disposed, etc).