‘Stupid’ Question 29: Do we need properties in c#?
I seriously felt a tiny itsi bitsy byte stupid for wondering about this, until a few days ago I came across a blog post discussing the cons of properties in C#. Secretly I didn’t quite see a difference between methods and properties, except for the syntax of course. So after reading the blog post (and honestly not quite understanding all of it) I decided to start asking around. First person to ask for me is always Kristoffer or James at work (Dotnet Mentor). This time it was Ruby fan, Jack of all trades – and master of many, James Kyburz. “James, do we really need properties in C#?”. He was first quiet for a few seconds, thinking, then he answered “No, not really”. We then had a long discussion about this.
I then looked around a bit on the beautiful web – and realized that this was a common question, something that has and is debated. How could I have missed this? So obviously it is not ‘given’ that we need properties. Methods or fields could suffice.
The way I understand it we can do without properties in C#
With that said, it doesn’t necessarily mean that the code will be ‘better’ if you avoid properties. As for the general guidelines for when to use what, I would consider that a separate question, but please feel free to start that discussion now :D You know I love comments!
If you are curios what the compiler makes out of methods, properties and fields here is the result I got when I ran this simple console app in Ildasm:
[sourcecode language=“csharp”]
namespace AppTest
{
class A
{public string Name { get; set; }}
class B
{public string Name(){return “”;}}
class C
{public string Name = “”;}
class Program
{static void Main(string[] args){}}
}
[/sourcecode]
ildasm
Result:
[sourcecode language=“csharp”]
Class A
.field private string ‘k__BackingField’
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance string
get_Name() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 11 (0xb)
.maxstack 1
.locals init (string V_0)
IL_0000: ldarg.0
IL_0001: ldfld string AppTest.A::’k__BackingField’
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method A::get_Name
.method public hidebysig specialname instance void
set_Name(string ‘value’) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld string AppTest.A::’k__BackingField’
IL_0007: ret
} // end of method A::set_Name
.property instance string Name()
{
.get instance string AppTest.A::get_Name()
.set instance void AppTest.A::set_Name(string)
} // end of property A::Name
Class B
.method public hidebysig instance string
Name() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldstr ""
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method B::Name
Class C
.field public string Name
[/sourcecode]
Comments
no in general they just shorten code and improve readability(and still have a private, protected variables).
For POCO objects I use them all the time, well auto properties that is. But for any other objects that use in a system, I don't really have a need them, if there is an object or variable that I need I’ll define it as a parameter on the method that requires it. Do we need them in C# maybe not, but they do make code more readable.
The nice thing with properties is heaving some different code-syntax to set up metadata without pass them as values in a method signature. Another nice thing is also the easy way to handle reflection, setters and getters in frameworks. Eg EF, NHib etc. Autoproperties are easy to set up and easy for ORM to bind to. You can also use logic to handle different requirements on property fields. It's harder to manage that with public fields. It's also easier to close the code and make it more immutable with it's state fields with properties instead of public fields. Add two methods instead of one to set and get is also nice and saves some annoying times. For DTOs with validations etc, properties are kind of cool. It's also harder to auto-map metadata to methods (you can do it) but it takes more code to handle that and you probably want the developers to use prefix for it. Kind or Get Set but that's kind of what properties can do for you. So I will say we need them though they give us lots of benefits. If you don't like them you can skip them. That's the best part. In Service classes that only do commands you probably don't need them, in settings, meta-data classes you will love them :) And thanks to protected, private setters, and the idea that you can bind validation to them etc you have nice class attribute that are defensive if you like defensive programming.
Up until WPF/SL/Blend/DataContext and data binding, properties where just one way to separate C# from java. Before then, properties could be used in VS or your own custom controls, but debates over chicken wings'n'beers abound. Then came WPF/XAML/data binding and now using properties in xaml (not methods) was in vogue! DOH! As you shown, properties EVENTUALLY get "cooked" into methods, so it's really all the same, BUT in XAML it's different and that's what we devs are more likely to look at (more so that IL code). This is NOT a stupid question, but rather one to differentiate jr from int devs quite quickly, especailly if you can NAME the methods which get created (I admit, I knew about it, but forgot the naming convention, so thank you). And even more so if you've done the Ildasm breakout (nicely done!). Good article, thanks and keep'em coming!
Properties are used to hide complexity and or limit accessibility on an object field (business entity for instance) class Person { public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get { return FirstName + " " + LastName; } } public DateTime BirthDate { get; set; } public int Age { get { return DateTime.Today.Year - BirthDate.Year; } } } FullName and Age is read-only and computed properties. The consumer of the object doesn't need to know how it is implemented. This is where property is being useful. Encapsulation
Properties look like fields, but are implemented as methods. Accessing a field is fast and side effect free (read access). Just make sure properties implementation does not surprise their users.
Well, technically, we don't "need" classes. (Examples are easier if I switch back to C/C++). One could write straight C code which will produce assembler output that's nearly identical to the assembler output of a very OO C++ program. (Early C++ compilers would actually generate C code which would than be run through a C compiler to create the final output). So the question becomes how much does the feature cost versus how much is easier readability/understandablity worth? The cost of a Property compared to a public field is minimal (call overhead). Compared to getter & setter methods, nothing at all. While I have great respect for Allen Holub's writings, in the article you cite he seems to be off the mark. While it seems he thinks he's writing about Properties as a syntactic element, he's really talking about exposing data as a concept. Everything he says about properties is equally true about public fields and getter/setter methods. He would probably have no problem at all with a property in the form "public String Name {get; private set;}"
Properties may be required in order to make dependency properties work in weird and wonderful work of WPF (though I am happy to be wrong on that one).
I normally only declare fields as private (unless constants) and use public properties. Why? Inheritance/virtual, interfaces, "lazy-loading", different visibility for get/set etc. POCOs and proxies within ORMs relies on public properties. If you have a value which requires some calculation before return. Properties are perfect since you can calculate the value the first time you access it and store the result in the backing field for future calls. If the execution time is too long though you should put in a method instead. One very important reason to use properties in favour of public fields is that you can't declare fields in interfaces, only properties. One problem with properties it does not work with ref / out. But sounds to me like a odd use anyway.
For the comment about properties being required for binding. you can effectively bind to fields with using this tool https://github.com/SimonCropp/Fielder
The point of the Dr Dobb's article has been, in my opinion, misunderstood. The author is not saying "Don't use properties, they are evil". Basically he is saying what a lot of people said before him: Don't use state mutators unless you have very good reasons. With properties, it is very easy to just declare everything public with get and set without bothering if the property should public or private. For a deeper understanding of mutable state, it is worth digging a bit into Functional Programming
Good read about this here Why Properties Matter
As @Tyrone said, they are syntactic sugar. Much more elegant than those ugly Getters and Setters.
Last modified on 2012-08-21