Comparing Fields and Methods
First, let's recap the original motivation for using methods to hide fields.
Consider the following struct that represents a position on a screen as an (X, Y)
coordinate pair:
struct ScreenPosition
{
public ScreenPosition(int x, int y)
{
this.X = rangeCheckedX(x);
this.Y = rangeCheckedY(y);
}
public int X;
public int Y;
private static int rangeCheckedX(int x)
{
if (x < 0 || x > 1280)
{
throw new ArgumentOutOfRangeException("X");
}
return x;
}
private static int rangeCheckedY(int y)
{
if (y < 0 || y > 1024)
{
throw new ArgumentOutOfRangeException("Y");
}
...
private static int rangeCheckedX(int x) { ... }
private static int rangeCheckedY(int y) { ... }
private int x, y;
}
The code now successfully enforces the range constraints, which is good. However, there
is a price to pay for this valuable guarantee—ScreenPosition no longer has a natural field-
like syntax; it uses awkward method-based syntax instead. The following example
increases the value of X by 10. To do so, it has to read the value of X by using the GetX
accessor method, and then write the value of X by using the SetX modifier method:
int xpos = origin.GetX();
origin.SetX(xpos + 10);
Compare this with the equivalent code if the X field were public:
origin.X += 10;
There is no doubt that, in this case, using fields is cleaner, shorter, and easier.
Unfortunately, using fields breaks encapsulation. Properties allow you to combine the
best of both examples: to retain encapsulation while allowing a field-like syntax.