Stupid .NET Tricks #1
August 6, 2007 1:09 pm programmingI’m working on a .NET/C# project, which is a new environment/language for me after years of Java development. Thusfar, .NET appears to be a pretty decent language, although most of the good stuff in the language directly mimics Java. .NET did managed to fix a few of the problems with Java, but also failed to fix ones that could have been fixed without the burden of backwards compatibility.
The reason for my post though is that .NET has introduced a few new problems that shouldn’t exist. Microsoft, with all their resources and plans for language domination, really should have known better. I’m calling these “Stupid .NET Tricks” in homage to Letterman.
My first example is one that bugs me on a daily basis:
For example:
public delegate int ValueGetter();
public void displayValue(ValueGetter getAValue) {
if ( weReallyWantToDisplayTheValue() ) {
int x = getAValue();
display(x);
}
}
private int aValue;
public int AValue {
get { return aValue; }
set { aValue = value; }
}
public void displayAValue() {
// This isn't allowed, even though it makes perfect sense
// displayValue(AValue);
// Instead, you have to do this:
displayValue( delegate() { return AValue; } );
}
Note that displayValue calls a method which calls a method on the property (both methods having the exact same signature), rather than just calling the method on the property itself.
Delegates are easily the best feature .NET has that Java doesn’t, but this oversight steals some of the thunder.

September 27th, 2007 at 4:38 pm
It makes perfect sense on why this does not work.
public void displayValue(ValueGetter getAValue)
is not expecting an int type EVER. What it is expecting, is basically a pointer to a delegate function.
Hence the need for you to wrap the property inside of a anonymous method.
If C# were to allow methods to accept either delegate types, or the delegate it selfs return type, then the language would not exactly be type safe.
September 27th, 2007 at 5:35 pm
> What it is expecting, is basically a pointer to a delegate function. Hence the need for you to wrap the property inside of a anonymous method.
My point is that we already have a valid method for the delegate-accepting method, and that’s the getter method for the property. However, if you create a property, you don’t get access to the getter method and thus can’t pass it around as a delegate. You have to (as you say) wrap it in an anon method, which is extra and unnecessary coding.
September 27th, 2007 at 6:13 pm
>My point is that we already have a valid method for the >delegate-accepting method, and that’s the getter method for >the property.
No, the getter method of a property is not a valid method strictly because the property is not a delegate type. If you compile it, the compiler will give you a type mismatch error (INT cannot be Delegate).
I understand your thinking, however how would you handle a property that has a setter as well?
Properties are not delegates, therefore its ludicrous to think that you should be able to pass one as such. Just because a property resembles a method, does not make it one, and only methods can be delegated.
To further complicate that, imagine if we could pass properties around as delegates. Imagine how hard it would be to follow the flow of the someone elses code, especially if it is not apparently obvious what they are doing.
In comparison
SomeMethod ( delegate() { return SomeProperty(); )};
It is incredibly obvious that SomeMethod accepts a Delegate, and that we are using that to pass the value of a property.
Makes perfect sense to me…or maybe its just my JavaScript closures experience talking.
However, if you create a property, you don’t get access to the getter method and thus can’t pass it around as a delegate. You have to (as you say) wrap it in an anon method, which is extra and unnecessary coding.
September 27th, 2007 at 7:43 pm
> Just because a property resembles a method, does not make it one
Properties are not methods themselves, but they are in fact syntactic sugar for at least one (and frequently two) methods. Despite Microsoft’s recommendations and standard practices, there is in fact no difference in the functionality of the property get and set accessors compared to standard methods; there’s only restrictions on their form (they’re restricted to certain names and signatures) and their allowed use (you can’t use them with delegates).
I’m fully aware that you can’t pass properties to delegate-accepting methods; my point is that the inability to do so is arbitrary, unnecessary, and makes for more complicated code.
Consider the code from my original example. The signature of displayValue() includes a parameter of type ValueGetter. Effectively displayValue states “I need something that will return an int in order to complete my task; please supply me with one.” It doesn’t want the int itself, as it may decide that it doesn’t need it after all — but if it does then it needs a way to get it. It also doesn’t impose any other type restrictions on the code that returns that int; unlike classes (which must derive from a specific type), any method that matches the ValueGetter signature will work.
The AValue property satisfies this; it includes a getter that is functionally identical to any method that satisfies the ValueGetter signature. However, .NET forbids you from passing the getter to the displayValue() method. Instead, you’re forced to wrap that method in extra code. This code doesn’t add any extra value; it just serves to satisfy the language specification. It’s also tempting to use an anonymous method (as you did in your example), which in turn leads to code duplication (multiple anonymous methods all providing access to the same property).
So, I’d hardly call it “ludicrous” to expect to be able to pass a property to a delegate parameter. As long as you understand that a property is just shorthand for one or two methods, then using it with a delegate is a natural and logical extension. The fact that you’re not allowed to is unfortunate, and that’s what prompted my post.
December 10th, 2007 at 10:24 am
I’m with you Craig!