C# 在泛型类的成员上使用nameof,但不指定类型参数 class-Foo { 公共T条(){/*…*/} }

C# 在泛型类的成员上使用nameof,但不指定类型参数 class-Foo { 公共T条(){/*…*/} },c#,c#-6.0,nameof,C#,C# 6.0,Nameof,我想将Bar的名称传递给Type.GetMethod(string)。我可以通过someType.GetMethod(nameof(Foo.Bar))来实现,但是int在这里是完全任意的;有什么办法可以省略吗?遗憾的是,nameof(Foo.Bar)不起作用 在这个玩具案例中,这没什么大不了的,但是如果有多个类型参数,特别是如果它们附加了where约束,那么将它们全部拼写出来就成了一项任务。特别指出,您想要做的是不允许的,不幸的是: 因为参数需要在语法上是一个表达式,所以 许多不允许列出的东西都

我想将Bar的名称传递给
Type.GetMethod(string)
。我可以通过
someType.GetMethod(nameof(Foo.Bar))
来实现,但是
int
在这里是完全任意的;有什么办法可以省略吗?遗憾的是,
nameof(Foo.Bar)
不起作用

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

特别指出,您想要做的是不允许的,不幸的是:

因为参数需要在语法上是一个表达式,所以 许多不允许列出的东西都没有用。以下 值得一提的是会产生错误:预定义类型(用于 例如,
int
void
),可空类型(
点?
),数组类型 (
Customer[,]
),指针类型(
Buffer*
),限定别名(
A::B
),以及 未绑定的泛型类型(
字典
,预处理符号(
调试
), 和标签(
循环:

您最好在界面中指定
Bar
,并使用
nameof(IFoo.Bar)
。当然,如果
Bar
在其签名中包含与
t
相关的内容(如本例中),则这不是一个选项


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

这有几个缺点:

  • 较大的API表面
  • 更困难、更容易出错的重构
  • 正在丢失编译时类型安全性,因为调用方可能使用
    对象
    接口

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

“例如,如果Bar在其签名中包含与T相关的内容”,这正是我的情况(编辑问题以包含此内容)。对于这种情况,我宁愿输入一些不必要的类型参数。首先,同时拥有
T
object
版本的
Bar
会使代码容易受到与
nameof
最初引入解决的相同类型的重命名后错误的攻击。如果我愿意容忍这种情况,那么只做
GetMethod(“Bar”)
会更简单。生活还在继续@dlf表示同意。将我的评论内容转移到子孙后代的答案中。
class Foo<T>
{
   public T Bar() { /* ... */ }
}