C#foreach循环导致无法找到CS 0246类型或命名空间

时间:2009-08-20 00:35:49

标签: c# scope foreach activator

我有一个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

类型

编译很好,但是当我运行它时,我得到以下内容:

Object reference not set to an instance of an object.

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

编辑:更新代码示例

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 个答案:

答案 0 :(得分:4)

必须在编译时知道泛型。您无法传入在运行时确定的类型。

所以你可以这样做:

(SomeType)Activator.CreateInstance<SomeType>;

但你不能这样做:

(currType)Activator.CreateInstance<currType>;

答案 1 :(得分:4)

currType是变量,而不是类型变量,因此您必须使用非泛型重载:

Object newObj = Activator.CreateInstance(currType);
                                        ^        ^

答案 2 :(得分: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;
    }
  }

答案 3 :(得分:0)

您必须初始化变量

public static List<IPlugin> Plugins=new List<IPlugin>();