[英]Passing type parameter to generic type with no constraints is throwing a constraint exception
请考虑以下代码:
IEnumerable<Type> oneParameterTypes = Assembly.GetAssembly(typeof(object))
.GetTypes()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericArguments().Length == 1)
.Where(t => t.GetGenericArguments().Single().GetGenericParameterConstraints().Length == 0);
oneParameterTypes
应该包含System.dll
程序oneParameterTypes
所有泛型类型,可以传递单个泛型类型参数并且不对其应用任何约束。
现在,让我们传入一个类型参数:
IEnumerable<Type> intParameterTypes = oneParameterTypes.Select(t => t.MakeGenericType(typeof(int)))
.ToList();
这应该有用,对吗? 我的意思是, oneParameterTypes
所有类型oneParameterTypes
应该没有类型约束,因此System.Int32
应该是有效类型。
然而,该行抛出以下异常:
'System.RuntimeType + ListBuilder`1 [T]'上的GenericArguments [0],'System.Int32'违反了类型'T'的约束。
什么是这个ListBuilder'1
类型,为什么它在oneParameterTypes
如果它有一个类型约束? 为什么我的Where
过滤器不起作用?
我认为克里斯是正确的。
试试这样:
IEnumerable<Type> oneParameterTypes = Assembly.GetAssembly(typeof (object))
.GetTypes()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericArguments().Length == 1)
.Where(t => t.GetGenericArguments().Single().GetGenericParameterConstraints().Length == 0 &&
!genericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint);
});
关于Type.GetGenericParameterConstraints
实际查找的内容,文档并不是很清楚:
使用IsClass属性来确定约束是否是基类约束; 如果属性返回false,则约束是接口约束。 如果类型参数没有类约束且没有接口约束,则返回空数组。
您可以隐式理解它只会检查基类或接口约束 。 要获得存在约束的完整图片,您需要对GenericParameterAttributes
进行额外检查。 您可以使用HasFlag
或按位掩码:
IEnumerable<Type> oneParameterTypes = Assembly.GetAssembly(typeof(object))
.GetTypes()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericArguments().Length == 1)
.Where(t => t.GetGenericArguments().Single().GetGenericParameterConstraints().Length == 0 && !t.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint);
typeof()或.GetType()方法不返回实际的类,而是返回Type Object表示,这将帮助我们将类型名称用作字符串。
相反,您可以使用反射类并查找该类型的类并将其用作参数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.