【问题标题】:Activator.CreateInstance(t, 42, args) cannot find constructorActivator.CreateInstance(t, 42, args) 找不到构造函数
【发布时间】:2009-06-11 16:06:40
【问题描述】:

我在工厂模式样式函数中使用(稍微扩展的版本)以下代码:



public class SingleItemNew : CheckoutContext { public BookingContext Data { get; set; } public SingleItemNew(BookingContext data) { Data = data; } } public CheckoutContext findContext(BookingContext data) { Type contextType = Type.GetType("CheckoutProcesses." + data.Case.ToString()); CheckoutContext output = Activator.CreateInstance(contextType, BindingFlags.CreateInstance, new[] { data }) as CheckoutContext; return output; }

但是,它在运行时会抛出一个 constructor not found 异常,我不知道为什么。

data.Case.ToString() 方法返回一个类的名称 SingleItemNew,该类的构造函数采用单个参数。

有人知道问题出在哪里吗?

干杯,埃德

【问题讨论】:

    标签: c# .net types activator createinstance


    【解决方案1】:

    试试这个:

      Type contextType = Type.GetType("CheckoutProcesses." + data.Case.ToString());
      CheckoutContext output = 
          (CheckoutContext)Activator.CreateInstance(contextType, data);
    

    您的代码不起作用的原因是Activator.CreateInstance 并没有真正具有您想要的重载。所以你可能想知道为什么代码会编译!原因是,它有一个重载,它采用与您的方法调用匹配的 (Type type, params object[] args),因此它可以编译,但在运行时,它会在您的类型中搜索一个采用 BindingFlagsBookingContext[] 的构造函数,这显然不是您的类型所具有的.

    【讨论】:

    • 正确,我显然不应该阅读课程的文档页面,他们在撒谎! (Activator.CreateInstance 的文档告诉您使用 (type, object[] params) 来调用具有相关参数数量的构造函数!) =D
    • 它不会说谎。它是否告诉您指定 BindingFlags,除非您真的需要它? ;)
    • 不,但是没有任何一个都行不通! (我一直在研究这个问题)=D
    • 对了,你可以随时在代码中的方法名上右击,使用Go to definition查看是哪一个重载被解决了。
    • Activator.CreateInstance 必须是整个 .NET Framework 中最令人困惑的重载集之一!
    【解决方案2】:

    构造函数是公开的吗?

    BookingContext类型的单个参数吗?

    问题在于,这显然是一个更大系统的一部分 - 如果您可以生成一个证明问题的short but complete program,它会非常更容易帮助您。然后我们可以修复该程序中的问题,您可以将修复移植回您的真实系统。否则我们真的只是在猜测:(

    【讨论】:

      【解决方案3】:

      SingleItemNew 构造函数是否将 BookingContext 作为参数?如果不完全匹配,则会失败:

      class ParamType   {    }
      class DerivedParamType : ParamType    {    }
      class TypeToCreate
      {
          public TypeToCreate(DerivedParamType data)
          {
              // do something
          }
      }
      
      ParamType args = new ParamType();
      // this call will fail: "constructor not found"
      object obj = Activator.CreateInstance(typeof(TypeToCreate), new object[] { args });
      
      // this call would work, since the input type matches the constructor
      DerivedParamType args = new DerivedParamType();
      object obj = Activator.CreateInstance(typeof(TypeToCreate), new object[] { args });
      

      【讨论】:

        【解决方案4】:

        这对我有用。

        Type.GetType("namespace.class, namespace");

        【讨论】:

          猜你喜欢
          • 2010-09-17
          • 2015-08-27
          • 1970-01-01
          • 2020-12-14
          • 2022-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多