Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In c#, why can't lambdas have extensions?

Tags:

c#

lambda

In Unity, here's a category in c#,

public static class HandyExtensions
{
public static IEnumerator Tweeng( this System.Action<float> v, float d )
    {
    while (..)
        {
        ..
        v( 13f*t );
        yield return null;
        }
    v(13f);
    }

Compiles fine!

But if you try to use it,

yield return StartCoroutine(
            ( (x)=>laser=x ).Tweeng(3.141f)
        );

this saddening error appears:

Assets/scripts/...cs(116,34): error CS0023: The .' operator cannot be applied to operand of typeanonymous method'

I have tears about this.

How could c# let us down?

Surely there's a way to call "on" a lambda like that, for an extension?

BTW the workaround is to go 3.14f.Tweeng((x)=>laser=x) but it's not as cool.

like image 986
Fattie Avatar asked Nov 30 '22 09:11

Fattie


1 Answers

I'm sorry this saddens you, but this choice was made deliberately by the language design team. The code which evaluates whether a given extension method is valid requires that the receiver have a clear type, and lambda expressions do not have a type.

There was some debate on this point, but ultimately it was decided that (1) the proposed feature is potentially confusing or error-prone if typeless expressions like lambdas, method groups and null literals get to be receivers of extension methods, and (2) the proposed feature is not at all necessary to make LINQ work. We were very constrained in our schedules when implementing C# 3 and anything that was not necessary to make LINQ work was cut. It was much easier to design, implement and test the feature of "don't allow lambdas as receivers" than to have to consider all the potentially odd cases where a lambda, method group or null was being used as the receiver.

As others have said, you can simply cast the lambda, or put it in a variable and then use the variable as the receiver.

Alternatively, as you note, you could consider using the float as the receiver in your specific example.

like image 148
Eric Lippert Avatar answered Dec 10 '22 06:12

Eric Lippert