2010-10-22 55 views
3

我想在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,不过,我得到

“酒吧。你好(字符串)'有错误的返回类型。

我试图代替ActionFunc玩耍,但似乎阻止我使用方法组语法。

任何想法?我的目标是能够引用许多具有不同返回类型和大量字符串参数的方法,我甚至不打算称它们 - 我只想反思它们的属性。不喜欢lambda表达式的安全,然而,而不只是键入方法名字符串)


编辑:澄清我的理由为希望使用Action<string>int在我的例子可以是任意数量的类型。我试着模板化该类型 -

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

- 但是编译器不能得到T(大概因为我不能在返回类型超载同样的原因?)。

还有其他想法吗?在这种情况下,我不反对某些疯狂的反思,只要我可以让编译器检查该方法组的名称即可。

回答

7

当它具有非无效返回类型时,它不再与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的方法组转换和类型推断进行了一些更改 - 不幸的是细节让我不知所措 - 但我不相信这种情况会受到这些更改的影响。

+0

有趣的博客文章。不幸的是,我希望在我的示例右侧存在的值的返回类型各不相同。我更新了一些信息。 – ladenedge 2010-10-22 16:13:03

+0

读者也可能对另一个相关的Lippert博客文章[Method Group Conversion Variance]感兴趣(http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in- C-部分三人基团的转化率 - variance.aspx)。 – ladenedge 2011-01-04 20:55:39

6

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

要处理多个返回类型 - 假设你不需要有返回值做任何事情 - 你可以平凡包装非void函数这样的:

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

感谢您的答案 - 不幸的是,我试图在我的真实程序中“分组”的方法都是不同的返回类型。我更新了一些信息。 – ladenedge 2010-10-22 16:15:22

+0

@ladenedge:我已经修改了我的答案(希望)可以解决您的评论。 – 2010-10-23 00:19:42

+0

我通常喜欢这个想法,但问题是我失去了方法组语法! (或者至少,我似乎无法在不显式传递's'的情况下编译它。)正如我上面提到的,我不仅有一堆返回类型,而且还有一堆字符串参数 - d真的很想避免把它们全部机械地传递给每一个'Hello'的外观。 – ladenedge 2010-10-23 05:00:48

相关问题