我目前的代码如下,我想解决的是摆脱try-catch:
public static bool IsNeverValidGenericArgument(this Type type) {
var elementType=type.GetElementType();
if(null!=elementType) {
if(type.IsArray)
try {
typeof(IList<>).MakeGenericType(elementType);
return false;
}
catch(ArgumentException) {
}
catch(TypeLoadException) {
}
return true; // pointer or byref
}
return
typeof(void)==type||typeof(RuntimeArgumentHandle)==type
||
typeof(ArgIterator)==type||typeof(TypedReference)==type;
}
我正在尝试编写动态类型构造的代码,我的代码将在每个传递的类型上调用 GetInterfaces()
,但是消费者代码传递的某些类型可能会导致内部 RuntimeType
中的 TypeLoadException
(例如 3.5 中的 typeof(ArgIterator).MakeArrayType().MakeArrayType()
,但不是 4.0+),我需要首先检查它是否永远不是有效的通用参数。 try-catch 有效,但效果不佳。
请注意,它抛出的情况可能因 .Net 框架的不同版本而异。
编辑:
该方法的替代版本是:
public static bool IsNeverValidGenericArgument(this Type type) {
var elementType=type.GetElementType();
if(null!=elementType) {
if(type.IsArray)
return elementType.IsNeverValidGenericArgument();
return true; // pointer or byref
}
return
typeof(void)==type||typeof(RuntimeArgumentHandle)==type
||
typeof(ArgIterator)==type||typeof(TypedReference)==type;
}
但这会将一些类型报告为无效,实际上这将不会导致 RuntimeType
中的异常,例如 typeof(ArgIterator).MakeArrayType(2) .MakeArrayType()
。
我知道有些类型通常不被使用,但我无法避免在消费者代码中使用它们。
最佳答案
当您尝试使用 typeof(ArgIterator).MakeArrayType().MakeArrayType()
参数构造泛型类型时,它是引发异常的内部 native CLR 代码。从该事实中得出的最重要的结论是,抛出的是 CLR 实现细节,而不是确定泛型类型参数有效性的标准或公开 API 的一部分。这意味着没有好的方法可以确定是否可以在不实际尝试的情况下构造泛型。 编辑:这也意味着没有好的方法来确定某些东西是否适用于特定版本的 CLR 而不适用于其他版本。
但是,更重要的是,如果您尝试构造一个带有无效参数的泛型类型,那确实是一种异常(exception)情况,正确的做法是抛出异常。我不能说你的代码做了什么,但如果你担心你的消费者使用导致 TypeLoadException
被抛出的类调用它,也许你应该让这些错误冒出来,这样消费者知道有问题。
TL;DR:您可能不应该做任何您想做的事情来处理异常情况。就让它扔吧。
关于c# - 如何检查类型是否永远不是有效的泛型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18078395/