What’s wrong with C#: Properties

Me>C# is just java with (often poorly thought out) additions
Zohar >Interesting. Which additions do you consider poorly thought out?

Well here’s one: Properties.

C# says:

public Foo Foo
{
set {this.foo = value;}
get {return foo;}
}
...
someFoo = Foo;

where java would say

public Foo getFoo() {return foo;}
public void setFoo(Foo foo) {this.foo = foo;}
...
someFoo = getFoo();

So what?

Well here’s some reasons I dislike this:

1. It is impossible in C# to have a setter at a different protection level to the getter. If you want a protected setter, you need to define a protected Foo SetFoo(Foo foo). Kind of defeats the purpose.

2. It is impossible in C# to overload a setter. This means that you can’t have what in java world would be good practice:

public void setFoo(Foo foo) {this.foo = foo;}
public void setFoo(MyFooLikeThing fooLikeThing) {
setFoo(fooLikeThing.asFoo());
}

You can of course still do this sort of thing in C#, but it is not overloading — the developer needs to know that x.Foo = foo and x.SetFoo(fooLikeThing) are the same thing. Two different syntaxes for the same operation does not aid easy comprehension or code readability.

3. In java it is clear if you do a = x.foo that you are not doing a function call and no side effect can happen. In C# a = x.Foo may be a simple getter or may instantiate a remote webservice. I can never know. And so I will assume the worst and comprimise my design to allow for the possibility that the get might do something expensive.

4. For some reason (probably to do at least partly with the limitations I mentioned above) the .NET libraries seem ambivalent on properties. Quite often you see x.GetFoo() where you might expect to see a property. the immediate questions are “Why is this not a property? What secret machinations are happening that means that it is not a prroperty? Should I treat this method differently to a true property?”. Truth is its probably just happenstance and the way the team felt on the day - but that doesn’t help me make a decision on how to use the method.

5. public Foo Foo {get;} — Come on! What were they thinking! Java’s Foo foo; is bad enough! At least there the case gives you a clue!

Of course all of the above is aesthetic. But that is what language is about — aesthetics and ease of comprehension.

5 Responses to “What’s wrong with C#: Properties”

  1. Zohar Says:

    Thanks for the example Chris.

    When I had to do C++ for a living, you would go to an interview and inevitably you would get a
    “What will the following code print?” code questions.
    These were carried through from the obfuscated C days ( http://www.de.ioccc.org/teaser/hello_2001.c) with the added benefit of the vastly enhanced syntactic mess that is C++.
    So far in My Java work ( none too long at about 3 years ) I have been able to easily read every class I have come across with ease. I might not understand the semantics, but the syntax is plain.
    Instead of those foolish C++ questions we now pair program with our candidates.
    Starting on C#, I read Don Box’s Essential .NET, Volume I: The Common Language Runtime : I’m sad to report he has one of those ” can you guess what will this C# code print…” .
    Well I can do even better , I can bugger off back to Java where I can concentrate on building semantically elegant systems with plain syntax.

  2. Eric Gunnerson Says:

    A few comments on your comments:
    1) You’re correct on this for current versions. We’ve decided to allow this in future versions.
    2) My model for properties is that they are just that, properties of an object. It seems really weird to me to say that a property could be of more than one type. If the setter can take more than one type, what is the type of the getter.
    If MyFooLikeThing is a replacement for Foo, then you could add a conversion operator that would allow you to use it in place of a Foo. This is a fairly rare occurence, however.
    3 & 4) This is a real concern, though in practice it hasn’t been a problem (at least for all the customers I’ve talked to). The reason you see some functions that say GetXXX() rather than a property is that they do something that would be unexpected in a property. It’s part of the design guidelines to approach things that way.

  3. Fernando Ribeiro Says:

    “It is impossible in C# to have a setter at a different protection level to the getter.”
    Why would you do that?
    We’ll be fine as long as both the getter and setter are protected when so it is the property.
    “It is impossible in C# to overload a setter.”
    Why would you do that?
    “This means that you can’t have what in Java world would be good practice.”
    Why would that be a good practice?
    “In Java it is clear if you do a = x.foo that you are not doing a function call and no side effect can happen.”
    Agreed.
    “For some reason the .NET libraries seem ambivalent on properties. Quite often you see x.GetFoo() where you might expect to see a property.”
    That’s odd but explained in the docs.

  4. Pete Beech Says:

    In general I think .NET is absolutely first class, but I also have a problem with properties causing side-effects.
    When trying to debug some ASP.NET code, I was tracing out either the Control.UniqueID or ClientID (can’t remember which), and the side-effect of just accessing the property was causing the problem I had to go away (something to do with FindControl being invoked, and walking down the control tree and causing something involving NamingContainer and automatic control naming to happen, which didn’t happen otherwise).
    I ended up having to decompile to see what exactly the side-effect was.
    That was pretty disconcerting, but I’m not sure how it could be improved. I don’t expect const functions will ever find their way into C#.
    In general I find properties really, really useful, but the odd case like the one above can be scary - especially since its in the actual framework code.

  5. Thomas Eyde Says:

    I hate when people ask me “why would you want to do that?”, instead of answer the question at hand or explain why I shouldn’t do it.
    For all you know, I have the best of reasons in the world to do it exactly that way.
    My take at C# is that it limits my freedom. If I want to override, why can’t I just do it? If I need to typecast, why can’t the compiler do it for me in the background? I have yet to see when the compiler error is actually meaningfull: If I declare an ArrayList and assing an object to it, guess what? I want an ArrayList! If my variable is typed, then the compiler knows if the typecast is valid or not. If my variable is of the object type, then nobody knows until runtime, so just leave it.
    Sadly for me, in .Net C# is the better option

Leave a Reply