8
class Foo<T>
{
   public T Bar() { /* ... */ }
}

我想将 Bar 的名字传递给Type.GetMethod(string). 我可以这样做someType.GetMethod(nameof(Foo<int>.Bar)),但这int在这里完全是任意的;有什么办法可以省略吗?可悲的是,nameof(Foo<>.Bar)不起作用。

在这个玩具案例中这没什么大不了的,但是如果有多个类型参数,特别是如果它们where附加了约束,那么将它们全部拼出来可能会成为一项任务。

4

1 回答 1

5

不幸的是,该nameof文档特别指出您想要做的事情是不允许的:

因为参数需要在语法上是一个表达式,所以有许多不允许列出的东西是无用的。以下值得一提的会产生错误:预定义类型(例如intor void)、可空类型(Point?)、数组类型(Customer[,])、指针类型(Buffer*)、限定别名(A::B)和 未绑定泛型类型(Dictionary<,>、预处理符号(DEBUG)、和标签 ( loop:)。

您可能做的最好的事情是Bar在界面中指定,然后使用nameof(IFoo.Bar). 当然,如果在其签名中Bar包含与相关的内容(例如在这种特定情况下),那不是一个选项。T


另一种选择是创建一个界面,其中每个T都替换为object. 然后具体类型显式地实现接口,也实现相同方法的泛型版本。

这有一些缺点:

  • 更大的 API 表面
  • 更困难和更容易出错的重构
  • 因为调用者可能使用object接口而失去编译时类型安全。

仅仅使用这可能是不合理的nameof,但在某些情况下,由于其他原因,这种策略是有意义的。在这些情况下,能够使用nameof只是一个方便的奖励。

于 2015-11-19T22:08:35.517 回答