この質問にはすでに答えがあります。
仕事中に既存のコードを読んで、私はこれがどのようにうまくいくことができるか疑問に思いました。アセンブリ内にクラスを定義しています。
[Serializable]
public class A
{
private readonly string _name;
private A(string name)
{
_name = name;
}
}
そして別のアセンブリでは:
public void f(Type t) {
object o = Activator.CreateInstance(t);
}
そしてその単純な呼び出しf(typeof(A))
AFAIKでは、ctorが宣言されている場合、コンパイラはデフォルトのpublicパラメータなしコンストラクタを生成することを想定していないため、パラメータなしのコンストラクタがないことについての例外が予想されました。
このコードは.NET 2.0で動作します。
[編集]すみませんが、私は実際のコードを読み違えています...私が提供したサンプルはそれを例示していません。 JonHの回答を受け入れたのは、それが良い情報を提供してくれたからです。
これを見なさい:リフレクションを使用してC#でデフォルトコンストラクタなしでtypeのインスタンスを作成する
これは未来へもあります、これはC#4.0に関してです:
Microsoftが2010年1月4日に投稿した 14:08
あなたのバグを確認しました その行動が あなたが説明したのは仕様によるものです。私たちは今 この問題をアーカイブしています。ご利用いただきありがとうございます Visual Studioと.NET Framework!Activator.CreateInstanceには多くのオーバーロードがあります。 単一の型パラメータのみを取ります デフォルトのパラメータなしを呼び出す コンストラクタ。を取るコンストラクタ のようなオプションのパラメータ あなたの例はデフォルトではありません コンストラクタそれらを呼び出すにはあなたが必要です に:
- 引数配列をとるオーバーロードを使う
- Type.Missingを引数として渡します
- BindingFlagsにOptionalParamBindingを指定する
これが一例です。
Activator.CreateInstance(typeof(MyClassName), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, new Object[] {Type.Missing}, null);
ありがとう、
ウェイタオ蘇
マイクロソフト株式会社
A
他の場所、またはロード元のアセンブリが更新されていません。それはコードの異常というよりはむしろプロジェクト/ソリューションの問題のように思えます。 - Codesleuth
代替案は:
object obj = System.Runtime.Serialization.FormatterServices
.GetUninitializedObject(t);
これはメモリ内にオブジェクトを作成しますがしない任意のコンストラクタを実行します。怖い。
これはあなたにとっては現実的ではないかもしれませんが、最も簡単なことは引数リストを型のように渡すことです。
Activator.CreateInstance(t、 "name");
あなたはf()が実際に何をしようとしているのかを考えたいでしょう。それはA型のオブジェクトをインスタンス化すべきでしょうか。他にどのようなクラスがインスタンス化されますか?
1つの可能性は、クラスAのCreateInstance()に正しいパラメーターを渡すswitchステートメントをf()内に含めることです。これは拡張できませんが、それは問題にならない可能性があります。
の混乱を招く2つの味がありますCreateInstance
:を取るもの物タイプのSystem.Type
としてパラメータ、別の型パラメータ
T
。
最初の1つ:
object Activator.CreateInstance(type As Type) { }
二つ目:
T Activator.CreateInstance<T>() { }
の二番目1つは、パブリックのパラメータのないコンストラクタがないとクラスには機能しないものです。
2番目のものを使用しても意味がありません。それが使用されるどんな場合でも、それは持っている方が良いでしょうwhere T : new()
あなたのクラスに制約を与え、単純にT
のコンストラクタ
のMSDNのドキュメント同意する:
一般的には、
CreateInstance
アプリケーションコードでは、 型はで知っている必要があるため コンパイル時間型がわかっている場合 コンパイル時、通常のインスタンス化 構文を使用することができます(new
演算子in C#、New
Visual Basicでは、gcnew
に C ++)
編集:話しすぎたのかもしれません。最初のバージョンも動作するはずがないようです。