0

以下の例は、その意図を示しています。この例では、オブジェクトの配列を反復処理し、デフォルト値がロードされた同じタイプの配列を作成しています。値自体をあるリストから次のリストにコピーする必要はありません。これは、リストの「タイプクローン」のようなものです。

以下のコードは、アクティベーターに対して次のエラーを生成します。

「System.Int32はGenericTypeDefinitionではありません。MakeGenericTypeは、Type.IsGenericTypeDefinitionがtrueであるタイプでのみ呼び出すことができます。」

Activator、CreateInstance、およびMakeGenericTypeの詳細は、まだ少し混乱しています。

エラーを回避するためにコードを変更するにはどうすればよいですか?

任意の提案をいただければ幸いです。

    private void Test()
    {
        object[] a = new object[] {100, "Text", new clsMyClass()};
        object[] b = new object[a.Length];

        for (int i = 0; i < a.Length; i++)
        {
            b[i] = Activator.CreateInstance(a[i].GetType().MakeGenericType());
        }

        for (int i = 0; i < b.Length; i++)
        {
            Console.WriteLine(b[i].GetType().ToString());
        }
    }

期待される出力は次のようになります。

  • System.Int32
  • System.String
  • MyNamespace.clsMyClass

結果の値は次のようになります。

  • b [0] = 0
  • b [1] = ""
  • b[2]=新しいclsMyClass
4

1 に答える 1

4

削除するMakeGenericType()と動作を開始します。これを使用してください

b[i] = Activator.CreateInstance(a[i].GetType());

MakeGenericTypeは、ジェネリックパラメーターを定義済みパラメーターに置き換えるためのものです。例として、配列にが含まれる場合List<T>、の呼び出しは a[i].GetType().MakeGenericType(typeof(int))タイプを返しList<int>ます。

あなたの場合、ジェネリック型は見当たらないので、なぜそれを使うのだろうか

また、そのように呼び出すActivator.CreateInstanceことは、型にパラメーターのないコンストラクターがある場合にのみ機能することに注意してください。これは、たとえば。の場合には当てはまりませんstringstringあなたはこのようなケースを扱うことができます

for (int i = 0; i < a.Length; i++)
{
   var oType = a[i].GetType();
   if (oType == typeof(string)) 
       b[i] = string.Empty; //or may be null 
   else
       b[i] = Activator.CreateInstance(oType);
}

パラメータなしのコンストラクタを使用せずに、すべての型に対して同様のことを行う必要があります。 Activator.CreateInstance(type, parameters...)仕事をすることができます。必要に応じて、リフレクションを使用して型コンストラクターのパラメーターを調査できます

于 2012-11-29T22:56:42.790 に答える