Consider this function:
static void Throw<T>(string message) where T : Exception
{
throw (T)Activator.CreateInstance(typeof(T), message, (Exception)null);
}
Given a type T of System.ArgumentException, as the question title says, I get a runtime error of "Ambiguous Match Found". Looking at the documentation for ArgumentException, the following are the public constructors:
ArgumentException()
ArgumentException(string)
ArgumentException(SerializationInfo, StreamingContext)
ArgumentException(string, Exception)
ArgumentException(string, string)
ArgumentException(string, string, Exception)
Given I am passing 2 arguments in to CreateInstance, and forcing the null to be a null Exception, I am struggling to understand why it is not matching the 4th constructor in the above list?
That will work:
static void Throw<T>(String message)
where T: Exception { // <- It's a good style to restrict T here
throw (T) typeof(T).GetConstructor(new Type[] {typeof(String)}).Invoke(new Object[] {message});
}
Typical Exception has 4 or more constructors, so we'd rather point out which one we want to execute. Often, we have to check if there's a suitable constructor:
static void Throw<T>(String message)
where T: Exception { // <- It's a good style to restrict T here
// The best constructor we can find
ConstructorInfo ci = typeof(T).GetConstructor(new Type[] {typeof(String)});
if (!Object.ReferenceEquals(null, ci))
throw (T) ci.Invoke(new Object[] {message});
// The second best constructor
ci = typeof(T).GetConstructor(new Type[] {typeof(String), typeof(Exception)});
if (!Object.ReferenceEquals(null, ci))
throw (T) ci.Invoke(new Object[] {message, null});
...
}
However, in your case you can put it with Activator:
static void Throw<T>(String message)
where T: Exception { // <- It's a good style to restrict T here
throw (T) Activator.CreateInstance(typeof(T), message);
}
This might work
static void Throw<T>(string message)
{
Exception ex = null;
throw (Exception)Activator.CreateInstance(typeof(T), message, ex);
}
I don't know where Exception is on this list, but my guess is it is as specific as string, otherwise there wouldn't be a problem. How does the method overload resolution system decide which method to call when a null value is passed?
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