When designing a type (I use the term type rather than class since the discussion here could just as well be applied to value types) they will typically use a field to store state internally. When exposing the state to consumers of the type, you can choose to do so by either making the field itself public or by creating a property through which the field is exposed. There is a third choice as well and that is to create methods that will get or set the value, but I will leave that out of the discussion for now (after all, this is what happens technically when exposing a field through a property).

public class SomeClass
{
    public int SomeValue;
}

The type above is about as simple as it gets. A class exposing a public field. Access to this field will be highly efficient since there is no extra wrapping around it; it is the field itself that is exposed. However, this is often not considered to be a good idea. There are several reasons for this. I will discuss some of them here.

Let's say that we release a class library with the above type in it, allowing others to use it in their code. Later we realize that we need to restrict the possible values that may be assigned to SomeValue. In fact, for some reason the value 42 is not acceptable. In order to enforce this restriction, we change our code so that SomeValue is now a property instead:

public class SomeClass
{
    private int _someValue;
    public int SomeValue
    {
        get { return _someValue; }
        set
        {
            if (value == 42)
            {
                throw new ArgumentException("value must be 42");
            }
            _someValue = value;
        }
    }
}

Bang! We just broke all code that is compiled against our type. Any code using your type must now be recompiled. This is perhaps the strongest argument against exposing fields directly; future-proofing. By wrapping field access into a property, you have created a platform where you can add validation without breaking any consuming code. This is a good thing to do, because we cannot see into the future. We have no idea how business requirements may change next month.

But wait, there is more. Do you use data binding? (I try to stay away from it, but that is just me). If you do, you may want to make sure that your types are data bindable. Currently, data binding works with properties, but not fields. If you choose to expose the field directly, you also choose not to support data binding.

Another nice feature that you get when exposing state through properties is that you can have different access levels on get and set operations:

public class SomeClass
{
    private int _someValue;
    public int SomeValue
    {
        get { return _someValue; }
        protected set
        {
            if (value == 42)
            {
                throw new ArgumentException("value must be 42");
            }
            _someValue = value;
        }
    }
}

Now SomeValue is designed so that any code can get the value, but only code in the SomeType class or any descendant class can set it. This kind of granularity of access control is not available with fields.

Given the arguments above, I would say that it is a good idea to default to exposing values through properties, unless there are very strong reasons not to. Then what about the internal code in the type itself? Should that code be allowed to use the field directly?

My personal, strong opinion is no, also the internal code should use the property (again, unless there are strong reasons not to). The main reason for this is what we can call debuggability: if you assign the value to the field in one, and only one place, you can easily track down what piece of code that is every now and then assigning that weird value that screws up the state of your program. Just set a breakpoint (or write to the log) in the property setter and wait for the offending code to make the call, then examine the stack trace. If you allow code to set the value in the field directly, this operation will be a lot more complicated.

I have stated that you should use the property unless there are strong reasons not to. What exactly do I consider strong reasons. Naturally, that depends on your code and what it does, but one example may be performance: if performance is very crucial, direct field access may be preferable. However: never optimize code for performance until you have measured it. Really. I cannot recall that I have ever come across a real-world case where this performance difference was an issue in any project that I have worked with.

Conclusion

I like to think about the property as a contract and the field as implementation. Any piece of code that needs to get or set the value should use the contract. Relying on the implementation should be done only when it is really needed.

kick it on DotNetKicks.com


I am working for a great consultancy company called Diversify, located in Sweden. We are hiring skilled .NET developers. If you are interested, don't hesitate to get in touch with me.

Comments

February 24. 2010 13:01

trackback

Code design: exposing fields or properties?

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

February 24. 2010 16:33

Pete

My friend, your first example is not exposing a field, but also exposing a property. Only that this property is the C# 2.0 syntactical sugar-version, which is totally future-proof to your second example.

I think maybe your first example should have been like this:

public class SomeClass {
    public int SomeValue = 0;
}

Pete

February 24. 2010 17:46

fredrik

Thanks Pete. You are correct, of course. I happened to paste the wrong code snipppet into the text when posting this, it is now corrected.

fredrik