C# delegate contravariance with lambda expression -
this question has answer here:
the second test method below not compile (cannot convert lambda expression target type d1
). mean (non-generic) delegate contravariance not work lambda expressions?
[testfixture] public class myvariancetests { private abstract class animal {} private class tiger : animal {} private delegate type d1(tiger tiger); private static type m1(animal animal) { return animal.gettype(); } [test] public void contravariantdelegatewithmethod() { d1 func = m1; type result = func(new tiger()); assert.areequal(result, typeof (tiger)); } [test] public void contravariantdelegatewithlambda() { d1 func = (animal animal) => animal.gettype(); type result = func(new tiger()); assert.areequal(result, typeof (tiger)); } }
you've identified inconsistency in language.
this called out explicitly in language specification:
7.15.1 anonymous function signatures
[...] in contrast method group conversions (§6.6), contra-variance of anonymous function parameter types not supported. [...]
...which raises question:
why didn't language designers bother supporting feature?
<speculation>
clearly, feature has small benefits. justify costs of complications required in compliant compiler implementation?
when write lambda expression, must already know delegate/expression-tree type being converted (there's no general-purpose type can "hold" arbitrary lambda). of c# 5, lambda (in contrast method) serves absolutely no purpose other in creation of single delegate / expression-tree instance. consequently, there's no advantage (other convenience) explicitly specifying more general type required parameter , expecting contra-variance support compiler. omit type , rely on type-inference (or, worst case, explicitly specify exact parameter-type required) without loss in reusability or expressibility.
this doesn't apply methods, serve other purposes other creation of delegates/expression-trees. may desire particular function signature (different delegate's) because appropriate, or require because must satisfy interface contract. further more, consider (as programmer creating delegate/expression-tree) don't "own" method in question (it in third-party assembly) when performing method-group conversion. never case lambdas.
it appears language-designers felt benefits of implementing contra-variance of parameter types lambdas didn't justify costs, unlike method-groups.
</speculation>
Comments
Post a Comment