简体   繁体   中英

Working with methods that return anonymous methods

If I have a class like this:

public class SomeClass
{
    public Action<string> SomeAction { get; set; }

    public SomeClass()
    {
        SomeAction = GetSomeAnonymousMethod();
    }

    private Action<string> GetSomeAnonymousMethod()
    {
        return (text) =>
        {
            Console.WriteLine(text);
        };
    }
}

What happens when I make a new instance of SomeClass ? My impression is that the constructor simply calls GetSomeAnonymousMethod() , which returns a new delegate instance (that only contains a reference to the compiler-generated backing method for the anonymous method), and assigns it to the SomeAction property.

Can someone confirm, or is something more sinister happening?

Well, that's nearly all that happens. In this particular case, your lambda expression (it's not an anonymous method, to be picky) doesn't need any state, so the generated method can be static, and a delegate reference can be cached. So the "new delegate instance" part may not be correct.

So it's more like this - at least when compiled with the MS compiler:

public class SomeClass
{
    private static Action<string> cachedAction;
    public Action<string> SomeAction { get; set; }

    public SomeClass()
    {
        SomeAction = GetSomeAnonymousMethod();
    }

    private Action<string> GetSomeAnonymousMethod()
    {
        Action<string> action = cachedAction;
        if (action == null)
        {
            action = AnonymousMethodImplementation;
            cachedAction = action;
        }
        return action;
    }

    private static void AnonymousMethodImplementation(string text)
    {
        Console.WriteLine(text);
    }
}

You don't need to worry about the details of this - and it's all an implementation detail... just a bit of an optimization. But if you really want to know what's going on, that's closer to reality.

As ever, to see the details of what the compiler's doing, you can always use ildasm (or Reflector in IL mode, for example) and see the generated IL.

Can someone confirm, or is something more sinister happening?

It seems like it's another secret action within the events of new and 2nd Cold War!

Yes, your constructor is doing what you're describing in your question.

I would explain that the anonymous delegate is converted into Action<string> using delegate type inference .

For example, the following code line:

return (text) =>
        {
            Console.WriteLine(text);
        };

...is infered to:

return new Action<string>((text) => 
{
     Console.WriteLine(text);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM