到目前为止我的代码如下所示,我想要解决的是摆脱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(例如typeof(ArgIterator)) .MakeArrayType().MakeArrayType()在3.5中,但不是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()构造一个泛型类型时,它是抛出异常的内部本机CLR代码.这个事实最重要的一点是,它是一个抛出的CLR实现细节,它不是标准或公开暴露的API的一部分,它决定了泛型类型参数的有效性.这意味着没有好的方法来确定是否可以在没有实际尝试的情况下构建泛型类型.编辑:这也意味着没有好的方法来确定某些东西是否适用于特定版本的CLR而不适用于另一种版本.
但是,更重要的是,如果您尝试构造具有无效参数的泛型类型,那确实是一种特殊情况,正确的操作过程就是抛出异常.我不能说你的代码做了什么,但是如果你担心你的消费者用引起TypeLoadExceptions的类调用它,也许你应该让这些错误冒出来让消费者知道存在问题.
TL; DR:您可能不应该做任何正在尝试处理异常情况的事情.让它扔掉.