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

为什么添加返回类型会阻止我使用方法组语法?

  •  3
  • ladenedge  · 技术社区  · 14 年前

    我试图在lambda表达式中使用方法组,如下所示:

    public class Foo { public void Hello(string s) { } }
    
    void Test()
    {
        // this works as long as Hello has a void return type
        Func<Foo, Action<string>> a = foo => foo.Hello;
    }
    

    当我更改返回类型时 Hello int 但是,我知道

    我试着玩 Func 代替 Action ,但这似乎阻止了我使用方法组语法。

    有什么想法吗?


    编辑 :澄清我想使用的原因 Action<string> : 在我的例子中,可能有多种类型。我试着做了那种模板--

    void Set<T>(Func<Foo, Func<string, T>> a) { }
    void Test() { Set(foo => foo.Hello); }  // fails
    

    --但是编译器不能 T (可能出于同样的原因,我不能重载返回类型?)。

    2 回复  |  直到 14 年前
        1
  •  7
  •   Jon Skeet    14 年前

    当它具有非void返回类型时,它不再与 Action<string> . 换句话说,这也会失败:

    int Foo(string s) { return 10; }
    
    // Error: wrong return type
    Action<string> action = new Action<string>(Foo);
    

    原因 为什么? 这是不允许的,见埃里克·利珀特的博客 "The void is invariant"

    您应该能够使用如下方法组语法:

    public class Foo { public int Hello(string s) { return 10; } }
    
    void Test()
    {
        Func<Foo, Func<string, int>> a = foo => foo.Hello;
    }
    

    这在VS2008和VS2010中对我都有效。C#4的方法组转换和类型推断发生了一些更改—不幸的是,这些细节让我无法理解—但我不认为这种情况会受到这些更改的影响。

        2
  •  6
  •   Marcelo Cantos    14 年前

    对于void返回类型,foo.Hello是 Action<string> . 对于int返回类型,它现在是 Func<string, int> .

    Func<Foo, Action<string>> a = foo => s => foo.Hello(s);