我有一个具有以下构造函数的类
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
的情况下,它会加载一个用户控件,该控件具有一个标签和一个滑块,允许用户设置DelayComposite
实例的“延迟”属性。
到目前为止,如果我没有将任何参数传递给构造函数,这可以正常工作。设计人员创建DelayCompositeDesigner
的实例,并将其分配给WPF ContentPresenter
的内容属性。
但是,因为该设计师需要修改所选DelayComposite
的属性
在设计器中,我必须将此实例传递给它。这就是为什么构造函数看起来像这样:
public DelayCompositeDesigner(DelayComposite CompositeObject)
{
InitializeComponent();
compositeObject = CompositeObject;
}
欢迎提出建议
@VolkerK
您的代码的结果是:
< ---- 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);
正如您所看到的,代码不了解DelayComposite
类型。
这解决了当前的问题,但为我想要实现的目标引入了许多新的问题, 无论哪种方式,谢谢你,感谢所有在这里回复的人。
以下代码,由多人建议:
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)});
结果是一样的。
答案 0 :(得分:15)
我认为你正在处理类型不匹配。
可能在不同的地方引用程序集,或者它们是针对不同的版本编译的。
我建议您遍历ConstructorInfo并对相应的参数执行paramtype == typeof(DelayComposite)
。
答案 1 :(得分:14)
我认为你的电话需要是:
var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4) });
当然,除非它 ,否则答案不会立即明显。
答案 2 :(得分:5)
虽然我讨厌类似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的输出窗口中打印了什么?
答案 3 :(得分:3)
如果你想调用这个构造函数......
public DelayCompositeDesigner(DelayComposite CompositeObject)
...只需使用它:
var designer = Activator.CreateInstance(typeof(DelayCompositeDesigner), new DelayComposite(4));
或
var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));
答案 4 :(得分:1)
我有类似的问题,但我的问题是由于构造函数的可见性。这个堆栈溢出帮助了我:
Instantiating a constructor with parameters in an internal class with reflection
答案 5 :(得分:1)
就我而言,此代码适用于 .NET Framework,但不适用于 .NET Core 3.1。它抛出无法捕获的 ExecutionEngineException
。但是当我将目标更改为 .NET 5 时,它运行良好。希望这对某人有所帮助。
Type type = assembly.GetType(dllName + ".dll");
Activator.CreateInstance(type ), new Stream[] { stream };
答案 6 :(得分:0)
我发现另一种创建对象实例的方法,而不是在answering关于SF的另一个问题时调用构造函数。
在 System.Runtime.Serialization 命名空间中,有一个函数 FormatterServices.GetUninitializedObject(type),它将创建一个不调用构造函数的对象。
如果您在Reflector中查看该功能,您将看到它正在进行外部呼叫。我不知道黑魔法是如何在引擎盖下发生的。但我确实向自己证明了构造函数从未被调用过但对象被实例化了。
答案 7 :(得分:0)
您可以在CreateInstance上使用以下重载:
public static Object CreateInstance(
Type type,
Object[] args
)
在你的情况下,它(我认为):
var designer = Activator.CreateInstance(
typeof(DelayCompositeDesigner),
new object[] { new DelayComposite(4) }
);
答案 8 :(得分:0)
我找到了问题的解决方案,我正在努力解决同样的问题。
这是我的激活者:
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" });
}
}
答案 9 :(得分:0)
遇到此问题时,我正在使用一种方法,该方法返回参数列表以插入Activator.CreateInstance,并且其参数数量与我尝试创建的对象的构造方法不同。