Fields and Properties are two important concepts that come up very early on when learning to code. Due to their surface level similarities it can be a confusing process understanding when to use each of them and why.
When?
Only ever use fields with the private access modifier. They can be used with protected or public but it's generally poor practice and I'll explain why later.
Use properties for all non-private scenarios, even if the properties are auto-implemented. You can also use them in a private context when implementing get and set logic.
public class ExampleClass { // This particular field is used as a 'backing' field // for PropertyWithLogic private int _myField; // protected, so a property, even though its an auto-property protected string AutoProperty { get; set; } // private but has logic, so a property private int PropertyWithLogic { get { return _myField; } set { _myField = value >= 0 ? value : 0; } } }
Why?
Good Object Oriented Programming is all about encapsulation, separating the interface of a class from its implementation. Interfaces are the blueprints for what a class should do, Classes are the how it does it.
The signature and implementation of a field are inseparable. That is to say, there is no separation of the what of a field (getting and setting of a value) from the how of a field (storing the value in memory). For this reason, fields are an implementation detail and can't be part of an interface.
Properties, on the other hand, separate signature from implementation. In the below example, the interface specifies that implementations must provide a property that you can get and it's the classes that define how that property is implemented.
public interface IExample { string Description { get; } } public class Example1 : IExample { // Returns a hard-coded string. public string Description { get { return "Example1"; } } } public class Example2 : IExample { private int _id; private DateTime _createdDate; // Performs some logic to return a string // that includes some member field values. public string Description { get { return string.Format( "Example2, id: {0}, created: {1}", _id, _createdDate); } } } public class Example3 : IExample { // Not implemented. Throws an exception when accessed. public string Description { get { throw new NotImplementedException("Todo!"); } } } public class Example4 : IExample { // Auto-property implementation, will return whatever // we set the value to. Value is stored in an // automatically generated backing field. public string Description { get; set; } }
Keeping interfaces separate from implementation in this way is a critical step in keeping the code you are writing from collapsing under its own weight over time.
An additional reason to use public automatic properties rather than public fields is that should you later need to add logic to the getter or setter, swapping from a field to a property is a breaking change for serialization as well as being a breaking change for backwards compatibility between dependent assemblies. Taking the time to do it right now will save you unnecessary difficulty when the application has grown or live data is involved.
Further Reading
This post has been all about fields versus properties, but it's worth noting that there's also a separate and equally important discussion of properties versus methods. Check out this excellent MSDN article comparing properties and methods.
I mention variations on the following topics in almost all Further Readings because understanding them inside and out means the difference between writing code that works and writing code that works and stands the test of time.
Even if you disagree with elements of generally accepted object oriented programming theory and go your own route, it's still an invaluable asset to have and I strongly recommend taking the time to assimilate it.
No comments:
Post a Comment