The code I have so far is as the following, what I want to solve is to get rid of the 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;
}
I'm trying to write the code of dynamic type construction, and my code will invoke GetInterfaces()
on each type passed, but some of the types passed by the consumers' code may cause a TypeLoadException
in RuntimeType
internally(e.g. typeof(ArgIterator).MakeArrayType().MakeArrayType()
in 3.5, but not 4.0+), I need to check if it is never a valid generic argument in the first place. try-catch works, but no good.
Note that the cases that it throws may vary with different version of .Net framework.
Edit:
An alternative version of the method is:
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;
}
But this will reports some types as invalid which in fact would not cause the exception in RuntimeType
, such as typeof(ArgIterator).MakeArrayType(2).MakeArrayType()
.
I know some types are not nomally used, but I can't avoid them to be used in the consumers' code.
When you try to construct a generic type with an argument of typeof(ArgIterator).MakeArrayType().MakeArrayType()
, it's internal native CLR code that throws the exception. The most important takeaway from that fact is that it's a CLR implementation detail that throws, and it's not part of a standard or a publicly-exposed API that determines the validity of a generic type argument. That means there's no good way to determine whether or not the generic type can be constructed without actually trying it. EDIT: That also means there's no good way to determine whether something will work on a particular version of the CLR and not work on another.
But, more importantly, if you try to construct a generic type with an invalid argument, that is truly an exceptional case, and the correct course of action is to throw an exception. I can't speak to what your code does, but if you're worried about your consumers invoking it with classes that cause TypeLoadException
s to be thrown, perhaps you should let those errors bubble up so the consumer knows that there's an issue.
TL;DR: You probably shouldn't be doing whatever you're trying to do to handle the exception case. Just let it throw.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With