繁体   English   中英

将类型参数传递给没有约束的泛型类型会引发约束异常

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM