对泛型类的成员使用 nameof,而不指定类型参数

本文关键字:类型参数 nameof 泛型类 成员 | 更新日期: 2023-09-27 18:23:43

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

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

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

对泛型类的成员使用 nameof,而不指定类型参数

nameof文档明确指出,不幸的是,您想要执行的操作是不允许的:

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

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


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

这有一些缺点:

  • 更大的 API 表面
  • 更困难且容易出错的重构
  • 由于调用方可能使用 object 接口而失去编译时类型安全性。

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