代码之家  ›  专栏  ›  技术社区  ›  TimothyP

Activator.CreateInstance找不到构造函数(MissingMethodException)

  •  15
  • TimothyP  · 技术社区  · 16 年前

    我有一个类,它有以下构造函数

    public DelayCompositeDesigner(DelayComposite CompositeObject)
    {
        InitializeComponent();
    
        compositeObject = CompositeObject;  
    }
    

    以及一个没有参数的默认构造函数。

    接下来,我尝试创建一个实例,但它只在没有参数的情况下工作:

    var designer = Activator.CreateInstance(designerAttribute.Designer);
    

    这很好,但是如果我想传递参数,它不会:

    var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));
    

    这将导致 MissingMethodException :

    构造函数voor类型 vialis.lightlink.controller.scenarios.composites.delaycompositedesigner 没有找到

    有什么想法吗?


    问题是我真的需要在构建过程中传递一个对象。

    你看,我有一个设计器,它加载从 CompositeBase . 然后将它们添加到一个列表中,用户可以从该列表中将它们拖动到设计器中。执行此操作后,将向设计器添加拖动的实例。这些类中的每一个类都有定义在其上的自定义属性:

    [CompositeMetaData("Delay","Sets the delay between commands",1)]
    [CompositeDesigner(typeof(DelayCompositeDesigner))]
    public class DelayComposite : CompositeBase
    {
    }
    

    当用户在设计器中选择一个项时,它会查看这些属性,以便为该类型加载设计器。例如,在 DelayComposite 它将加载一个用户控件,该控件有一个标签和一个滑块,允许用户设置 延迟复合材料 实例。

    到目前为止,如果我不将任何参数传递给构造函数,这就可以正常工作。设计器创建 DelayCompositeDesigner 并将其分配给WPF的内容属性 ContentPresenter .

    但由于该设计器需要修改所选的 延迟复合材料 在设计器中,我必须将此实例传递给它。这就是为什么构造函数看起来是这样的:

    public DelayCompositeDesigner(DelayComposite CompositeObject)
    {
        InitializeComponent();
    
        compositeObject = CompositeObject;
    }
    

    欢迎提出建议


    @ VolkerK

    代码的结果是:

    <--FO vialis.lightlink.controller.scenarios.composites.delaycompositedesignervoid cTROR() vialis.lightlink.controller.scenarios.composites.delaycompositedesignervoid .ctor(vialis.lightlink.controller.scenarios.composites.delaycomposite) 参数:vialis.lightlink.controller.scenarios.composites.delaycomposite 福科公司


    Leppie,你是对的,我在我的UI应用程序中引用了复合材料程序集。这不是我在运行时加载时应该做的事情。以下代码有效:

    object composite = Activator.CreateInstance(item.CompositType,(byte)205);
                        var designer = Activator.CreateInstance(designerAttribute.Designer, composite);
    

    正如您所看到的,代码不知道 延迟复合材料 类型。

    这就解决了目前的问题,但为我想要实现的目标引入了许多新的问题, 不管怎样,谢谢你,也感谢所有在这里回复的人。


    以下代码由多人推荐:

    var designer = Activator.CreateInstance(
        designerAttribute.Designer, 
        new object[] { new DelayComposite(4) } 
    );
    

    这个 Activator.CreateInstance 签名如下:

    Activator.CreateInstance(Type type, params object[] obj)
    

    所以它应该接受我的代码,但我将尝试建议的代码

    更新:

    我已经按照建议尝试过了:

    var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4)});
    

    结果是一样的。

    9 回复  |  直到 6 年前
        1
  •  15
  •   nawfal Donny V.    11 年前

    我认为你正在处理一个类型不匹配的问题。

    可能是在不同的地方引用了程序集,或者是根据不同的版本编译的。

    我建议您遍历constructorInfo并执行 paramtype == typeof(DelayComposite) 在适当的参数上。

        2
  •  13
  •   DocMax    16 年前

    我想你的电话应该是:

    var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4) });
    

    当然,除非 在这种情况下,答案并不明显。

        3
  •  5
  •   nawfal Donny V.    11 年前

    虽然我讨厌像printf那样的调试…

    public static void foo(Type t, params object[] p)
    {
        System.Diagnostics.Debug.WriteLine("<---- foo");
        foreach(System.Reflection.ConstructorInfo ci in t.GetConstructors())
        {
            System.Diagnostics.Debug.WriteLine(t.FullName + ci.ToString());
        }
        foreach (object o in p)
        {
            System.Diagnostics.Debug.WriteLine("param:" + o.GetType().FullName);
        }
        System.Diagnostics.Debug.WriteLine("foo ---->");
    }
    // ...
    foo(designerAttribute.Designer, new DelayComposite(4));
    var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));
    

    在Visual Studio的输出窗口中打印的是什么?

        4
  •  3
  •   Ishmaeel    16 年前

    如果你想叫这个承包商…

    public DelayCompositeDesigner(DelayComposite CompositeObject)
    

    …就用这个:

    var designer = Activator.CreateInstance(typeof(DelayCompositeDesigner), new DelayComposite(4));
    

    var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));
    
        5
  •  1
  •   Community Jaime Torres    7 年前

    我有一个类似的问题,但是我的问题是由于构造函数的可见性。这个堆栈溢出帮助我:

    Instantiating a constructor with parameters in an internal class with reflection

        6
  •  0
  •   Community Jaime Torres    7 年前

    我发现了另一种不用调用构造函数就创建对象实例的方法。 answering 关于SF的另一个问题。

    System.Runtime.序列化 命名空间有一个函数 FormatterServices.GetUninitializedObject(类型) 它将在不调用构造函数的情况下创建对象。

    如果你在Reflector中看到这个函数,你会发现它正在进行一个外部调用。我不知道黑魔法在引擎盖下到底发生了什么。但我确实向自己证明了从未调用构造函数,但对象是实例化的。

        7
  •  0
  •   erlando    16 年前

    可以在CreateInstance上使用以下重载:

    public static Object CreateInstance(
        Type type,
        Object[] args
    )
    

    在你的情况下(我想):

    var designer = Activator.CreateInstance(
        typeof(DelayCompositeDesigner), 
        new object[] { new DelayComposite(4) } 
    );
    
        8
  •  0
  •   Louis Marais    8 年前

    我找到了解决问题的办法,我也在同一个问题上挣扎。

    这是我的激活器:

    private void LoadTask(FileInfo dll)
        {
            Assembly assembly = Assembly.LoadFrom(dll.FullName);
    
            foreach (Type type in assembly.GetTypes())
            {
                var hasInterface = type.GetInterface("ITask") != null;
    
                if (type.IsClass && hasInterface)
                {
                    var instance = Activator.CreateInstance(type, _proxy, _context);
                    _tasks.Add(type.Name, (ITask)instance);
                }
            }
        }
    

    这里是我要激活的类,注意我必须将构造函数参数更改为对象,这是使它工作的唯一方法。

    public class CalculateDowntimeTask : Task<CalculateDowntimeTask>
    {
        public CalculateDowntimeTask(object proxy, object context) : 
            base((TaskServiceClient)proxy, (TaskDataDataContext)context) { }
    
        public override void Execute()
        {
            LogMessage(new TaskMessage() { Message = "Testing" });
            BroadcastMessage(new TaskMessage() { Message = "Testing" });
        }
    }
    
        9
  •  0
  •   Mike Cheel    6 年前

    当我遇到这个问题时,我正在使用一个方法,该方法将参数列表返回到Activator.CreateInstance插件,并且它的参数数目与我试图创建的对象的构造函数的参数数目不同。

    推荐文章