我有一个具有以下构造函数的类

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;  
}

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

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

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

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

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

这导致MissingMethodException

  

构造函数类型   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesigner   没找到

这里有什么想法吗?


问题是我真的需要在施工期间传递一个物体。

您看到我有一个设计器可以加载从CompositeBase继承的所有类型。然后将这些添加到列表中,用户可以从中将它们拖动到设计器。执行此操作后,将拖动的实例添加到设计器中。每个类都定义了自定义属性:

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

当用户选择设计器中的项目时,它会查看这些属性以便为该类型加载设计器。例如,在DelayComposite的情况下,它将加载具有标签和滑块的用户控件,该标签和滑块允许用户设置<!> quot; Delay <!> quot; DelayCompositeDesigner实例的属性。

到目前为止,如果我没有将任何参数传递给构造函数,这可以正常工作。设计者创建ContentPresenter的实例并将其分配给WPF Activator.CreateInstance的content属性。

但是因为那个设计师需要修改所选<=>的属性 在设计器中,我必须将此实例传递给它。这就是为什么构造函数看起来像这样:

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;
}

欢迎提出建议


@VolkerK

您的代码的结果是:

  

<!> lt; ---- foo   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid   .ctor()   Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid   .ctor(Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite)   PARAM:Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite   foo ---- <!>>;


Leppie,你是对的,我出于某种原因在我的UI应用程序中引用了Composites程序集......这不是我在运行时加载它时应该做的事情。以下代码有效:

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(Type type, params object[] obj)

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

<强>更新

我按照建议尝试了这个:

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

结果是一样的。

有帮助吗?

解决方案

我认为你正在处理类型不匹配。

可能在不同的地方引用程序集,或者它们是针对不同的版本编译的。

我建议您遍历ConstructorInfo并对相应的参数执行paramtype == typeof(DelayComposite)

其他提示

我认为你的电话需要是:

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

当然,除非它 ,否则答案不会立即明显。

虽然我讨厌类似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的输出窗口中打印了什么?

如果你想调用这个构造函数...... ...只需使用它:

public DelayCompositeDesigner(DelayComposite CompositeObject)

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

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

使用参数实例化构造函数带有反思的内部课程

我发现了另一种创建对象实例的方法,而根本没有调用构造函数,而回答关于SF的另一个问题。

System.Runtime.Serialization 命名空间中,有一个函数 FormatterServices.GetUninitializedObject(type),它将创建一个不调用构造函数的对象。

如果您在Reflector中查看该功能,您将看到它正在进行外部呼叫。我不知道黑魔法是如何在引擎盖下发生的。但我确实向自己证明了构造函数从未被调用过但对象被实例化了。

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

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

在你的情况下,它(我认为):

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

我找到了问题的解决方案,我正在努力解决同样的问题。

这是我的激活者:

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

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

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

当我遇到这个问题时,我使用了一个返回参数列表的方法来插入Activator.CreateInstance,它的参数数量与我试图创建的对象的构造函数的数量不同。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top