如何确定类实例上通用参数的值
时间:2020-03-06 14:31:31 来源:igfitidea点击:
我有一个标记接口定义为
public interface IExtender<T>
{
}
我有一个实现IExtender的类
public class UserExtender : IExtender<User>
在运行时,我将UserExtender类型作为我的评估方法的参数
public Type Evaluate(Type type) // type == typeof(UserExtender)
如何使我的评估方法返回
typeof(User)
基于运行时评估。我确定反射涉及其中,但我似乎无法破解。
(我不确定如何表达这个问题。我希望它足够清楚。)
解决方案
有一个示例,我们可以按照我们在MSDN文档中描述的GetGenericTypeDefinition方法进行操作。它使用GetGenericArguments方法。
Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
foreach (Type tParam in typeArguments)
{
Console.WriteLine("\t\t{0}", tParam);
}
在示例中,我认为我们想将t替换为this。如果那不能直接起作用,则可能需要使用GetInterfaces方法执行一些操作,以枚举我们类型上的当前接口,然后从该接口类型中枚举" GetGenericArguments()"。
我根据提供的一些花絮走了。它可以变得更健壮,以便在接口上处理多个通用参数。...但我并不需要它;)
private static Type SafeGetSingleGenericParameter(Type type, Type interfaceType)
{
if (!interfaceType.IsGenericType || interfaceType.GetGenericArguments().Count() != 1)
return type;
foreach (Type baseInterface in type.GetInterfaces())
{
if (baseInterface.IsGenericType &&
baseInterface.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition())
{
return baseInterface.GetGenericArguments().Single();
}
}
return type;
}
我对问题的理解与其他答案完全不同。
如果评估签名可以更改为:
public Type Evaluate<T>(IExtender<T> it)
{
return typeof(T);
}
这不需要更改调用代码,但是需要参数的类型为IExtender <T>,但是我们可以轻松地获得T类型:
// ** compiled and tested UserExtender ue = new UserExtender(); Type t = Evaluate(ue);
当然,它不像仅使用" Type"参数那样通用,但这是对该问题的不同看法。另请注意,存在反射的安全注意事项[msdn]

