动态抛出“System.ArgumentException”时出现“模糊匹配”

时间:2014-01-30 11:25:54

标签: c# .net reflection

考虑这个功能:

static void Throw<T>(string message) where T : Exception
{
    throw (T)Activator.CreateInstance(typeof(T), message, (Exception)null);
}

给定T的{​​{1}}类型,如问题标题所示,我收到“发现不明确的匹配”的运行时错误。查看System.ArgumentException的文档,以下是公共构造函数:

ArgumentException

鉴于我将2个参数传递给ArgumentException() ArgumentException(string) ArgumentException(SerializationInfo, StreamingContext) ArgumentException(string, Exception) ArgumentException(string, string) ArgumentException(string, string, Exception) ,并强制CreateInstance为空null,我很难理解为什么它不匹配第4个构造函数上面的列表?

2 个答案:

答案 0 :(得分:3)

这将有效:

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});
}

典型Exception 4 或更多构造函数,因此我们宁愿指出我们要执行哪一个。通常,我们必须检查是否有合适的构造函数:

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});
  ...
}

但是,在您的情况下,您可以使用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);
}

答案 1 :(得分:1)

这可能有效

static void Throw<T>(string message)
{
    Exception ex = null;
    throw (Exception)Activator.CreateInstance(typeof(T), message, ex);
}

我不知道此列表中Exception的位置,但我的猜测与string具体相同,否则就不会有问题。 How does the method overload resolution system decide which method to call when a null value is passed?