【发布时间】:2016-07-04 10:24:47
【问题描述】:
注意:这个问题是关于技术方面的,不是关于设计决策的。回答或评论不同的设计并不回答这个问题,因为我只对这个特定问题的技术方面的性质感兴趣。
在C# 6.0 我有这个方法,我传递了一个IEnumerable<T>:
public void MyMethod(IEnumerable<object> list) { ... }
假设调用者在 MyClass[] 数组上调用它。
我想要的是泛型类型定义的类名,我有这个方法的实现:
public void MyMethod(IEnumerable<object> list)
{
...
var name =
from abstraction in list.GetType().GetInterfaces()
where abstraction.IsGenericType
&& abstraction.GetGenericTypeDefinition() == typeof(IEnumerable<>)
from genericArgumentType in abstraction.GetGenericArguments()
select genericArgumentType.Name;
...
}
现在在这种情况下(在方法的主体内),这会正确返回类的名称(例如,字符串 "MyClass")。所以我尝试将其重构为一个开放的通用扩展方法,如下所示:
public static string GetGenericTypeDefinitionName<T>(this IEnumerable<T> list)
{
var name =
from abstraction in list.GetType().GetInterfaces()
where abstraction.IsGenericType
&& abstraction.GetGenericTypeDefinition() == typeof(IEnumerable<>)
from genericArgumentType in abstraction.GetGenericArguments()
select genericArgumentType.Name;
return name.Single();
}
然后像这样从MyMethod() 内部调用GetGenericTypeDefinitionName():
public void MyMethod(IEnumerable<object> list)
{
...
var name = list.GetGenericTypeDefinitionName();
...
}
这也有效,但后来我意识到:'嘿!为什么不只是return typeof(T).Name?'
结果它返回了字符串"Object",而我预期的结果与之前的实现相同(例如"MyClass")。
是否有可能获得预期的类型?在处理开放的泛型类型T 时,似乎所有信息都丢失了。
另外为什么我没有得到预期的类型? C# 的这种特定行为的技术细节是什么?
【问题讨论】:
-
你能说明你是如何调用它的,以便
typeof(T).Name返回"Object"吗? -
您是否有机会使用泛型方差?
IEnumerable<SomeType>可以分配给IEnumerable<object>。 -
@RenéVogt 我已经编辑了问题以显示扩展方法的调用方式和位置。
-
@QuantumHive 编辑中添加的示例与我在下面的答案中推测的完全一致;如果它实际上是
List<SomeType>,那么:您使用的是通用方差 -
@QuantumHive 要让它工作,你需要它是
MyMethod<T>(IEnumerable<T> list),等等
标签: c# .net generics reflection