C# 在泛型类的成员上使用nameof,但不指定类型参数 class-Foo { 公共T条(){/*…*/} }
我想将Bar的名称传递给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约束,那么将它们全部拼写出来就成了一项任务。特别指出,您想要做的是不允许的,不幸的是: 因为参数需要在语法上是一个表达式,所以 许多不允许列出的东西都
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() { /* ... */ }
}