在不指定类型参数的情况下对泛型 class 的成员使用 nameof
Use nameof on a member of a generic class without specifying type arguments
class Foo<T>
{
public T Bar() { /* ... */ }
}
我想把 Bar 的名字传给 Type.GetMethod(string)
。我可以用 someType.GetMethod(nameof(Foo<int>.Bar))
来做到这一点,但是 int
在这里完全是任意的;有什么办法可以省略吗?遗憾的是,nameof(Foo<>.Bar)
不起作用。
在这个玩具箱中这没什么大不了的,但如果有多个类型参数,尤其是如果它们附加了 where
约束,将它们拼写出来可能会成为一项任务。
nameof
documentation 明确表示你想做的事情是不允许的,不幸的是:
Because the argument needs to be an expression syntactically, there
are many things disallowed that are not useful to list. The following
are worth mentioning that produce errors: predefined types (for
example, int
or void
), nullable types (Point?
), array types
(Customer[,]
), pointer types (Buffer*
), qualified alias (A::B
), and
unbound generic types (Dictionary<,>
), preprocessing symbols (DEBUG
),
and labels (loop:
).
您可能做的最好的事情是在界面中指定 Bar
,然后使用 nameof(IFoo.Bar)
。当然,如果 Bar
在其签名中包含与 T
相关的内容(例如在这种特定情况下),则这不是一个选项。
另一种选择是创建一个界面,其中每个 T
都替换为 object
。然后具体类型显式实现接口,同时实现相同方法的泛型版本。
这有一些缺点:
- 更大的API表面
- 更困难和容易出错的重构
- 失去编译时类型安全,因为调用者可能使用
object
接口。
仅使用 nameof
这可能是不合理的,但在某些情况下,由于其他原因,此策略是有意义的。在那些情况下,能够使用 nameof
只是一个方便的奖励。
class Foo<T>
{
public T Bar() { /* ... */ }
}
我想把 Bar 的名字传给 Type.GetMethod(string)
。我可以用 someType.GetMethod(nameof(Foo<int>.Bar))
来做到这一点,但是 int
在这里完全是任意的;有什么办法可以省略吗?遗憾的是,nameof(Foo<>.Bar)
不起作用。
在这个玩具箱中这没什么大不了的,但如果有多个类型参数,尤其是如果它们附加了 where
约束,将它们拼写出来可能会成为一项任务。
nameof
documentation 明确表示你想做的事情是不允许的,不幸的是:
Because the argument needs to be an expression syntactically, there are many things disallowed that are not useful to list. The following are worth mentioning that produce errors: predefined types (for example,
int
orvoid
), nullable types (Point?
), array types (Customer[,]
), pointer types (Buffer*
), qualified alias (A::B
), and unbound generic types (Dictionary<,>
), preprocessing symbols (DEBUG
), and labels (loop:
).
您可能做的最好的事情是在界面中指定 Bar
,然后使用 nameof(IFoo.Bar)
。当然,如果 Bar
在其签名中包含与 T
相关的内容(例如在这种特定情况下),则这不是一个选项。
另一种选择是创建一个界面,其中每个 T
都替换为 object
。然后具体类型显式实现接口,同时实现相同方法的泛型版本。
这有一些缺点:
- 更大的API表面
- 更困难和容易出错的重构
- 失去编译时类型安全,因为调用者可能使用
object
接口。
仅使用 nameof
这可能是不合理的,但在某些情况下,由于其他原因,此策略是有意义的。在那些情况下,能够使用 nameof
只是一个方便的奖励。