Several C# questions on StackOverflow ask how to make anonymous delegates/lambdas with out
or ref
parameters. See, for example:
To do so, you just need to specify the type of the parameter, as in:
public void delegate D(out T p);
// ...
D a = (out T t) => { ... }; // Lambda syntax.
D b = delegate(out T t) { ... }; // Anonymous delegate syntax.
What I'm curious about is why the type is explicitly required. Is there a particular reason that this is the case? That is, from a compiler/language standpoint, why isn't the following allowed?
D a = (out t) => { ... }; // Lambda syntax -- implicit typing.
D b = delegate(out t) { ... }; // Anonymous delegate syntax -- implicit typing.
or even better, just:
D a = (t) => { ... }; // Lambda syntax -- implicit typing and ref|out-ness.
D b = delegate(t) { ... }; // Anonymous delegate syntax -- implicit typing and ref|out-ness.
In lambda expressions, you can't use the ref or out parameters.
Lambda expression is an anonymous method that you can use to create delegates or expression tree types. Microsoft introduced Lambda Expression in C# 3.0 sometime in 2007. Most of the time, anonymous methods are confused with lambda expression by many developers.
Anonymous methods provide a technique to pass a code block as a delegate parameter. Anonymous methods are the methods without a name, just the body. You need not specify the return type in an anonymous method; it is inferred from the return statement inside the method body.
Interesting question.
First, consider the difference between anonymous methods and lambdas. From the compiler writer's perspective, the most important difference is that lambdas can require the compiler to infer the type of the parameters from the target to which the lambda is being assigned; C# 2 anonymous methods do not have this feature. This feature seems like a small difference but in fact it has major ramifications on the implementation of the compiler. See my blog series on this topic for some thoughts on why that is:
http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx
So now let's come to your actual question: why can we not infer outness/refness from the target type to the parameters of the lambda. That is, if we have delegate void D(out int x) then surely D d = x=> { x = 10; } could infer that x is "out int".
There's no technical reason I'm aware of why we could not do that. Internally in the compiler the out/ref types are represented as types like any other.
However, features do not get done just because they can be done; they get done because there's a compelling reason to do so. For lambdas, the compelling reason to do type inference in the first place is LINQ; we want to be able to do a simple syntactic transformation on a query comprehension into a method call with lambdas, and let the method type inference engine work out the types of all the lambda parameters. None of the LINQ methods generated have delegates with out or ref parameters.
So, we have no compelling reason to do the feature. Delegates which have out/ref parameters are relatively rare. And assignment of lambdas to those delegates is rarer still. So this is a feature that we don't need, and that benefits almost no one.
C# 3 was the "long pole" on the Visual Studio schedule; we had the most number of days of work scheduled of any team that ships a component in VS. That meant that every day we slipped the schedule, the entire division slipped. That was a powerful disincentive to spending time on unnecessary features that benefitted no one. So the work was never done.
I agree that it would be nice to be more consistent here, but it's unlikely to happen. We have many higher priorities.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With