Fields vs. Properties

One element of C# that is very useful is the Property member.  Back in the days of C you would declare a struct and the members of that struct (the fields) were all public.  When C++ came along it gave use the concept of hiding our fields behind accessor methods, namely getters and setters.  Java continued this design.  C# introduces a new member type called the property, which makes managing your field getters and setters a little bit easier.  So where you might have Java code like:


public class MyClass
{
  private int myValue;

  public int getMyValue() { return myvalue; }
  public void setMyValue(int value) { myValue = value; }
}

Your C# code might look like this:

public class MyClass
{
  private int myValue;
  public int MyValue
  {
    get { return myValue; }
    set { myValue = value; }
  }
}

It's a subtle difference, but the IDE and language pickup on that syntax and make organizing your "function" methods seperately from your "attribute" methods much easier.  In fact, the latest version of the .NET framework includes a handy syntax feature called auto-properties which let you condense that declaration to:

public class MyClass
{
  public int MyValue { get; set; }
}

Here the private variable is auto-generated by the compiler.  The advantage to providing getters and setters, regardless of your language choice, is that you can later create a derived class that provides additional actions based on the setting or getting of the attribute.  So you might have:

public class MyClassWithSmallValues : MyClass
{
  public override int MyValue
  {
    get { return base.MyValue; }
    set 
    { 
      if ( value > 10 || value
      {
        throw new ArgumentException();
      }
      base.MyValue = value;
    }
  }
}

That example is pretty contrived, but you get the idea.

So where does that leave our old friend the public field?  It is still legal syntax to declar a public variable on your class, i.e.

public class MyClass
{
  public int MyValue;
}

At the base class level, this class would behave identically to either the Java or C# implementation above, and it saves you a bit of coding.  So why is this considered "bad practice"?  Well, as mentioned above, you are now trapped with that attribute on your class.  No matter how many levels of derivation you go, you will always have a MyValue and you have no way of reacting to request or change to that variable.  Still, there are times when this construct can be useful.  If it were bad in all cases the language maintainers would simply strip it out.  Here is a case where I find the public field to still be useful:

public class MyClass
{
  public readonly byte[] MyByteArray = new byte[4];
}

The goal in this implementation is to provide a class that has an array of bytes that is exactly 4 bytes long.  It can never be less, it can never be more.  Each element in the array always has a legal value for a byte.  The readonly keyword above is to instruct the C# compiler that this value can only be set once, and only at the time the class is created.  It can never be written to again, but it can be read.  A user of the class could change the values at each index of the array, but they could never modify the array itself.

The net result is that you save yourself from creating a lot of error catching code.  You don't have to check for the array to be too short or too long, nor for the array being null.  The property is indexable right off an instance of the class, and that without needing to create your own Collection class (which was a bear until MS introduced generics in the framework).  

The one drawback I can see to this implementation is that certain framework components will inspect class properties, but do not perform reflection to find public fields.  So where a DataGridView will data bind to all of the properties in a class automatically, it completely ignores your public fields.  That's just as well, because I don't think that control behaves properly with arrays, but it is worth mentioning.

So to all of the OO programmers of the world: do you still have a use for the public field?  Or is this a concept that can be eliminated from modern compilers?
 

0 comments:

 
Jade Mason