Activator.CreateInstanceはコンストラクターを見つけることができません(MissingMethodException)
-
03-07-2019 - |
質問
次のコンストラクタを持つクラスがあります
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
のコンテンツプロパティに割り当てます。
ただし、そのデザイナーは選択した<=>のプロパティを変更する必要があるため デザイナーでは、このインスタンスを渡さなければなりません。そのため、コンストラクターは次のように見えます。
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 ---- <!> gt;
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));
同様の問題がありましたが、私の問題はコンストラクタの可視性によるものでした。このスタックオーバーフローは私を助けました:
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);
}
}
}
そして、ここにアクティブにするクラスがあります。コンストラクターのパラメーターをオブジェクトに変更する必要があったことに注意してください。これを機能させる唯一の方法です。
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にプラグインしましたが、作成しようとしたオブジェクトのコンストラクターとは異なる数の引数がありました。