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

发布于 2024-09-28 07:18:18 字数 983 浏览 4 评论 0原文

我尝试在 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 时,我得到

“Bar.Hello(string)”的返回类型错误。

我尝试使用 Func 代替 Action,但是那似乎阻止我使用方法组语法。

有什么想法吗?

(我的目标,fwiw,是能够引用许多具有不同返回类型和大量字符串参数的方法。我什至不打算调用它们 - 我只是想反映它们的属性。我确实喜欢安全性但是,与仅输入方法名称字符串相比,使用 lambda 表达式。)


编辑:澄清我想要使用 Action 的原因:int 在我的示例中可以是多种类型中的任何一种。我尝试模板化该类型 --

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

-- 但编译器无法派生 T (大概出于同样的原因我无法重载返回类型?)。

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

I'm trying to use a method group in a lambda expression, like this:

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;
}

When I change the return type of Hello to int, however, I get

'Bar.Hello(string)' has the wrong return type.

I've tried playing around with Func in place of Action, but that seems to prevent me from using the method group syntax.

Any ideas?

(My goal, fwiw, is to be able to refer to numerous methods that have different return types and lots of string arguments. I don't even intend to call them - I just want to reflect over their attributes. I do like the safety of lambdas, however, versus just typing in method name strings.)


Edit: to clarify my reasons for wanting to use Action<string>: int in my example may be any of a number of types. I tried templating that type --

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

-- but the compiler can't derive T (presumably for the same reasons I can't overload on return type?).

Any other ideas? I'm not opposed in this case to some crazy reflection as long as I can get the compiler to check the name of that method group.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〆一缕阳光ご 2024-10-05 07:18:18

当它具有非 void 返回类型时,它不再与 Action 兼容。换句话说,这也会失败:

int Foo(string s) { return 10; }

// Error: wrong return type
Action<string> action = new Action<string>(Foo);

有关不允许这样做的原因,请参阅 Eric Lippert 的博客文章 "虚空是不变的"

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

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 的方法组转换和类型推断发生了一些更改 - 不幸的是,我没有注意到细节 - 但我不认为这种情况会受到这些更改的影响。

When it has a non-void return type, it's no longer compatible with Action<string>. In other words, this would fail too:

int Foo(string s) { return 10; }

// Error: wrong return type
Action<string> action = new Action<string>(Foo);

For the reasons why this isn't allowed, see Eric Lippert's blog post on "The void is invariant".

You should be able to use method group syntax like this:

public class Foo { public int Hello(string s) { return 10; } }

void Test()
{
    Func<Foo, Func<string, int>> a = foo => foo.Hello;
}

That works for me in both VS2008 and VS2010. There have been some changes to method group conversions and type inference for C# 4 - the details escape me unfortunately - but I don't believe this case is affected by those changes.

往事随风而去 2024-10-05 07:18:18

对于 void 返回类型,foo.Hello 是一个 Action。对于 int 返回类型,它现在是 Func

要处理多种返回类型 - 并假设您不需要对返回值执行任何操作 - 您可以简单地包装非 void 函数,如下所示:

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

With a void return type, foo.Hello is an Action<string>. With an int return type, it's now a Func<string, int>.

To handle multiple return types — and assuming you don't need to do anything with the return value — you can trivially wrap non-void functions thus:

Func<Foo, Action<string>> a = foo => s => foo.Hello(s);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文