1

タイプのリストを循環し、それぞれのインスタンスを作成するforeachループがあります。ただし、ビルドすると、CS0246エラーが発生します(「タイプまたは名前空間が見つかりませんでした...」)。コードの簡略化されたバージョンは次のとおりです。

internal static class TypeManager
{
    internal static void LoadTypes()
    {
        // Fill the list with types

        // Create instances of each type
        foreach (Type currType in Types)
        {
            Type aType = currType; // comiles fine
            Object newObj = (currType)Activator.CreateInstance<currType>; // CS 0246
        }
    }

    public static List<Type> Types;
}

編集:フォローアップの質問

私のforeachループは次のようになります。

foreach (Type currType in Types)
{
    Types.Add((Type)Activator.CreateInstance(currType));
}

タイプリストはオブジェクトタイプになりました

これは正常にコンパイルされますが、実行すると次のようになります。

Object reference not set to an instance of an object.

これを2行に分割して、最初にオブジェクトを作成してからリストに追加すると、最初の行は問題ありません(オブジェクトは正常に作成されます)が、同じエラーメッセージが表示されます。

編集:コードサンプルを更新

internal static LoadPlugins()
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (typeof(IPlugin).IsAssignableFrom(currType))
        {
            Assembly.LoadFrom(currFile.FullName);
            Object pluginInstance = Activator.CreateInstance(currType); // Compiles and runs fine
            Plugins.Add((IPlugin)pluginInstance); // NullReferenceException
            break;
        }
    }
}

public static List<IPlugin> Plugins;
4

4 に答える 4

4

ジェネリックはコンパイル時に認識されている必要があります。実行時に決定されたタイプを渡すことはできません。

だからあなたはこれを行うことができます:

(SomeType)Activator.CreateInstance<SomeType>;

しかし、これを行うことはできません:

(currType)Activator.CreateInstance<currType>;
于 2009-08-20T00:41:41.780 に答える
4

currTypeは型変数ではなく変数であるため、非ジェネリックオーバーロードを使用する必要があります。

Object newObj = Activator.CreateInstance(currType);
                                        ^        ^
于 2009-08-20T00:42:44.713 に答える
1

フォローアップのために:「ジェネリック」と「リフレクション」の概念の違いに混乱しているようですが、両方を読んでおくとよいでしょう。

フォローアップの質問については、Activator.CreateInstanceの結果をSystem.Typeにキャストしていますが、実際には実際のタイプにキャストする必要があります。実際のタイプにキャストバックする場合は、追加のランタイムチェックが必要です。

たぶん、このコードはあなたが理解するのを助けることができます:

  var types = new List<Type>
    {
      typeof (string),
      typeof (DateTime)
    };

  foreach (Type t in types)
  {
    // creates an object of the type represented by t
    object instance = Activator.CreateInstance(t);

    // this would cause an InvalidCastException, since instance is not of type 
    // System.Type, but instead either of type System.String or System.DateTime
    // Type t2 = (Type) instance;

    // to cast back to the actual type, additional runtime checks are needed here:

    if (instance is System.String)
    {
      string s = (string) instance;
    }

    else if (instance is DateTime)
    {
      DateTime d = (DateTime) instance;
    }
  }
于 2009-08-20T06:28:59.570 に答える
0

変数を初期化する必要があります

public static List<IPlugin> Plugins=new List<IPlugin>();
于 2011-07-26T18:05:17.897 に答える