Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Corner case in using lambdas expression in base constructor

In the Framework we are building we need the following pattern:

public class BaseRenderer
{
    Func<string> renderer;
    public BaseRenderer(Func<string> renderer)
    {
        this.renderer = renderer;
    }

    public string Render()
    {
        return renderer();
    }
}

public class NameRenderer : BaseRenderer
{
    public string Name{ get; set; }

     public NameRenderer ()
        : base(() =>this.Name)
     {}
}

As you see, we create a lambda when calling the base constructor.

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new NameRenderer(){Name = "Foo"}.Render());
    }
}

Oddly, when trying to actually use the lambda it throws NullReferenceException (Console Application), or some kind of ExecutionEngineExceptionexception (Web app on IIS).

I think the reason is that this pointer is not ready before calling base constructor, so the lambda is unable to capture this.Name at this stage.

Shouldn't it throw an exception in "capture time" instead of "execution time"? Is this behavior documented?

I can refactor the code in a different way, but I think it worths a comment.

like image 887
Olmo Avatar asked Dec 09 '09 18:12

Olmo


1 Answers

As asgerhallas correctly points out, this should not be legal according to the specification. We accidentally allowed this bogus usage to sneak by the error detector that searches for incorrect usages of "this" before it is legal to do so. I've fixed the bug; the C# 4 compiler correctly flags your program as an error.

Many apologies for the inconvenience; this was my mistake.

like image 106
Eric Lippert Avatar answered Nov 11 '22 17:11

Eric Lippert