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

Types List 现在是 Object 类型

这编译得很好,但是当我运行它时,我得到以下信息:

Object reference not set to an instance of an object.

如果我将它分成两行,首先创建一个对象,然后将其添加到列表中,第一行很好(对象创建成功),但它给了我相同的错误消息。

编辑:更新代码示例

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 回答