代码之家  ›  专栏  ›  技术社区  ›  BFree

将扩展方法传递给需要委托的方法。这是怎么工作的?

  •  10
  • BFree  · 技术社区  · 15 年前

    所以在工作中,我使用了一个我们没有编写的API,其中一个方法接受了委托。出于某种原因,我想到了一个适合这个签名的扩展方法,所以我想知道它是否有效。我确信这不会,但令我惊讶的是,确实如此。请允许我演示:

    假设我有这些课程:

    public interface IMyInterface
    {
    
    }
    
    public class MyClass : IMyInterface 
    { 
    
    }
    
    public static class Extensions
    {
        public static string FuncMethod(this IMyInterface imy, int x)
        {
            return x.ToString();
        }
    }
    

    现在假设我在某个地方有一个方法签名,它看起来像这样:

        private static void Method(Func<int, string> func)
        {
    
        }
    

    现在我的扩展方法(看起来像它)与这个签名匹配,但是我们都知道扩展方法只是冒烟和镜像,所以它 真的不 匹配那个签名。然而,我可以安全地做到这一点:

    var instance = new MyClass();
    Method(instance.FuncMethod);
    

    我的问题是,这是如何工作的?编译器为我生成了什么使这个可以接受。扩展方法的实际签名采用 IMyInterface 但是 Func 不是吗?我在幕后发生了什么?

    2 回复  |  直到 15 年前
        1
  •  10
  •   Community Mohan Dere    8 年前

    实例方法实现为隐藏 this 参数。

    从扩展方法创建实例委托时,隐藏的 参数作为第一个普通参数传递给方法。

    Note that this cannot be done with value types .

        2
  •  3
  •   Amy B    15 年前

    我不知道编译器究竟在做什么来允许这些场景,但是期望看起来是合理的。也许这个代码示例将有助于抓住这个概念。

    MyClass instance = new MyClass();
    Func<int, string> f1 = instance.FuncMethod;
    Func<int, string> f2 = (i) => instance.FuncMethod(i);
    Func<int, string> f3 = (i) => Extensions.FuncMethod(instance, i);