Martin Fowler blogged about C# properties a couple weeks back saying that he “.. liked the notion of properties right from the start..” because it’s “.. much more natural to write obj.X = other.X.” Further, ” … from a language point of view, properties and fields look the same. So if I have a field x which I can just read and write to, I can just declare it as a field. I don’t worry about this violating encapsulation, because should I wish to do something more fancy I can just replace it with a property later. It all saves a lot of typing of stupid accessor functions.” For those of you who have never used C#, instead of writing this in Java:
// Java getter & setter
private String foo;
public String getFoo() {
return this.foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
// access the private variable foo like this:
bar = obj.getFoo();
you can write this:
// C# public property
private String _foo;
public String Foo {
get { return _foo; }
set { _foo = value; }
}
// access the private variable _foo like this:
bar = obj.Foo;
I initially liked this feature of C# as well, it definitely seems more natural to use properties. Also, like Martin mentions, it saves you from having to make decisions about encapsulation.. do you use a getX()/setX() method or do I just mark it as public? With C#, you can change the implementation without changing your published API.
Martin points out that in this case beauty is only skin deep. If you use reflection to access the public properties or fields of a C# class, you might be surprised to see that the implementation does in fact change. In the example above, the property ‘Foo’ gets turned into 2 methods: get_Foo() and set_Foo(), which you can see using reflection:
Type type = (typeof(YourClassName));
MemberInfo [] members;
members = type.GetMembers(BindingFlags.Public|BindingFlags.Instance);
Console.WriteLine( "\nThe public instance members of class '{0}' are : \n", type);
for (int i =0 ; i
Martin ends by noting "... now I have to write stupid accessor functions for accessible data values." which is something that your IDE can do for you. In Eclipse, declare your private instance variables and then right click --> Source --> Generate Getter & Setter...
Hey, Aaron, you might be interested in this (not my post, BTW)…
http://cgi.skizz.plus.com/blog/dev/archives/000154.html
Chris Stevenson expounded on some problems he had with properties in C#.
FWIW in Groovy (a scripting language for the JVM) we decided that non-private fields were bad for encapsulation and are disallowed; so we can just use normal field declaration notation for declaring most properties.
e.g.
http://groovy.codehaus.org/beans.html
If you need to declare custom getters/setters you can – otherwise the language does it for you.
AJ (or anyone else here) – I’m not quite sure I understand the problem. Why is it bad that, when using reflection, the methods come up as get_X and set_X?
How does this remove the benefit of being able to do ob.X = val and have it call a method automatically?
Ray: the idea (or at least what I thought the idea was) is that a property (ie: String foo = obj.bar;) allows you to mimic the behavior of a public field, while maintaining encapsulation. Further, in theory, it allows you to change the implementation of a instance variable from a public field to a property without affecting any of the external classes that use this class, ie: they wouldn’t need to be modified/recompiled if you decided to change from a field to a property. What the above example shows is that while for the most part the appearance is the same, the implementation does in fact change and if an external class was using reflection to access a field, changing it to a property would require a change in the external class, which is bad.
I think the “not having to write accessors until I need them” argument for properties is a red herring. Not only do accessor calls look different than field accesses when you reflect on the class metadata, but much worse, the IL is different. So if you change a public field to a property, you’ve just broken binary compatibility with your previous version–anyone who compiled against your old version will have to compile again with the new.
However, I don’t think properties are without benefit. I think they really come into their own when used with frameworks that use reflection and attributes. Both the Java and C# communities use properties, it’s just that C# has support for them in the language itself, which makes some things a lot cleaner.
For example, Ant tasks. When writing a custom task for Ant, any XML attributes you want to receive in your class need to be exposed as getters/setters. In Java:
public string getLogfile() { … }
public void setLogfile(string logfile) { … }
In C# (with NAnt):
[TaskAttribute(“logfile”, Required=true)]
public string Logfile {
get { … }
set { … }
}
The fact that C# explicitly recognizes the concept of properties means you have a convenient place for describing them, and that whether something represents a property or a method is completely unambiguous (as opposed to Java where you have to glob get*/set*/is*, which always felt a little wrong to me).
In this example, C# properties allowed the NAnt authors to make a property attribute that lets you customize the name of the attribute, and specify whether it is required or not. (IIRC, in Java-based Ant, you have to explicitly validate your tag state when your tag starts executing–i.e. you have to check for the presence of required values yourself.)
I personally am not a huge fan of C# properties but I don’t like the arguments I’ve heard against them. Vis-a-vis Java accessors, they’re an improvement. But then, I tend to be wary of accessors in general…
You might be interested in this: http://www.geocities.com/csharpfaq/properties.html
Properties seem attractive at first, but as most (all?) abstractions they are leaky.
You can reflect explicitly on properties, and find them as properties.
You can choose to ignore the technical implementations of the get_X and set_X when you reflect methods too.
So I fail to see the problem…
The JIT compiler inlines the simple properties, so there is no difference between accesing a field and using a property. That’s why properties should always do simple things, like setting or retrieving a member field, and avoid doing complex computation.
C# public properties make code more readable to me: there is NO ambiguity between C# public properties and public methods proper. C# public fields, while POSSIBLE and convenient to create, have always been generally regarded as bad coding practice. C# get/set just FEELS right and makes public property manipulation seem more natural.
In java you could do something similar to properties if you don’t like the normal get_x set_x style. Define a class like this:
public class Property {
private T m_data;
public T get() {return m_data;}
public void set(T data) {m_data = data;}
}
Then instead of write get/sets for your instance variables you could define them like this:
public final Property myString = new Property();
public final Property myInteger = new Property();
Thanks a lot!
@TC: But what if you want to have different manipulation between your string and integer property, and then what if you have two integers with different validations/data manipulation, as far as i can understand with your approach you would need to create new Property classes for each one of them…