簡體   English   中英

Activator.CreateInstance 找不到構造函數 (MissingMethodException)

[英]Activator.CreateInstance can't find the constructor (MissingMethodException)

我有一個具有以下構造函數的類

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的 content 屬性。

但是由於該設計器需要修改設計器中選定的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)});

結果是一樣的。

我認為您的電話需要是:

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

當然,除非這樣,在這種情況下,答案並不是很明顯。

我認為您正在處理類型不匹配。

程序集可能在不同的地方被引用,或者它們是針對不同的版本編譯的。

我建議您遍歷 ConstructorInfo 並在適當的參數上執行paramtype == typeof(DelayComposite)

雖然我討厭類似 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));

要么

var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));

我有一個類似的問題,但是我的問題是由於構造函數的可見性。 這個堆棧溢出幫助了我:

使用反射在內部類中使用參數實例化構造函數

回答關於 SF 的另一個問題時,我發現了另一種無需調用構造函數即可創建對象實例的方法。

System.Runtime.Serialization命名空間中,有一個函數FormatterServices.GetUninitializedObject(type)將在不調用構造函數的情況下創建一個對象。

如果您在 Reflector 中查看該函數,您將看到它正在進行外部調用。 我不知道黑魔法實際上是如何發生在引擎蓋下的。 但我確實向自己證明了構造函數從未被調用,但對象已被實例化。

當我遇到這個問題時,我使用了一個返回參數列表的方法來插入到 Activator.CreateInstance 並且它的參數數量與我試圖創建的對象的構造函數不同。

就我而言,此代碼適用於 .NET Framework,但不適用於 .NET Core 3.1。 它拋出無法捕獲的ExecutionEngineException 但是當我將目標更改為 .NET 5 時,它運行良好。 希望這對某人有所幫助。

Type type = assembly.GetType(dllName + ".dll");
Activator.CreateInstance(type ), new Stream[] { stream };

您可以在 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);
            }
        }
    }

這是我要激活的類,請注意,我必須將構造函數參數更改為對象,這是我讓它工作的唯一方法。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM