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

C#foreach循环导致找不到CS 0246类型或命名空间,c#,scope,foreach,activator,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循环,它循环遍历一个类型列表,并为每个类型创建一个实例。但是,当我构建时,它会给出一个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;
}
类型列表现在为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;
内部静态加载插件()
{
foreach(在pluginAssembly.GetTypes()中键入currType)
{
if(typeof(IPlugin).IsAssignableFrom(currType))
{
Assembly.LoadFrom(currFile.FullName);
Object pluginInstance=Activator.CreateInstance(currType);//编译并运行良好
Add((IPlugin)pluginInstance);//NullReferenceException
打破
}
}
}
公共静态列表插件;

编译时必须知道泛型。不能传入在运行时确定的类型

所以你可以这样做:

(SomeType)Activator.CreateInstance<SomeType>;
(SomeType)Activator.CreateInstance;
但你不能这样做:

(currType)Activator.CreateInstance<currType>;
(currType)Activator.CreateInstance;

编译时必须知道泛型。不能传入在运行时确定的类型

所以你可以这样做:

(SomeType)Activator.CreateInstance<SomeType>;
(SomeType)Activator.CreateInstance;
但你不能这样做:

(currType)Activator.CreateInstance<currType>;
(currType)Activator.CreateInstance;

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

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

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

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

对于后续内容:您似乎对“泛型”和“反射”这两个概念之间的差异感到困惑,您可能想了解这两个概念

至于您的后续问题:您正在将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;
    }
  }
var类型=新列表
{
类型(字符串),
类型(日期时间)
};
foreach(类型中的类型t)
{
//创建由t表示的类型的对象
object instance=Activator.CreateInstance(t);
//这将导致InvalidCastException,因为实例不是类型
//System.Type,但不是System.String或System.DateTime类型
//类型t2=(类型)实例;
//要回溯到实际类型,此处需要额外的运行时检查:
if(实例为System.String)
{
字符串s=(字符串)实例;
}
else if(实例为DateTime)
{
DateTime d=(DateTime)实例;
}
}

对于后续内容:似乎您对“泛型”和“反射”这两个概念之间的差异感到困惑,您可能想了解这两个概念

至于您的后续问题:您正在将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;
    }
  }
var类型=新列表
{
类型(字符串),
类型(日期时间)
};
foreach(类型中的类型t)
{
//创建由t表示的类型的对象
object instance=Activator.CreateInstance(t);
//这将导致InvalidCastException,因为实例不是类型
//System.Type,但不是System.String或System.DateTime类型
//类型t2=(类型)实例;
//要回溯到实际类型,此处需要额外的运行时检查:
if(实例为System.String)
{
字符串s=(字符串)实例;
}
else if(实例为DateTime)
{
DateTime d=(DateTime)实例;
}
}

必须初始化变量

public static List<IPlugin> Plugins=new List<IPlugin>();
publicstaticlist插件=newlist();

必须初始化变量

public static List<IPlugin> Plugins=new List<IPlugin>();
publicstaticlist插件=newlist();

了解泛型很好。最后我改为非泛型的CreateInstance()方法(如下面dtb所建议的)。最后,我改为非泛型的CreateInstance()方法(如下面dtb所建议的)。接下来:我认为这是因为泛型需要在编译时被知道(感谢Joseph),但我将类型集合改为ArrayList(即没有泛型),这并没有解决问题。有什么建议吗?请显示用于填写列表的代码。特别是,您是否真的使用
new
创建了实例?对于后续操作:我认为这是因为需要在编译时知道泛型(感谢Joseph),但我将类型集合更改为ArrayList(即没有泛型),这并没有解决问题。有什么建议吗?请显示用于填写列表的代码。特别是,您是否确实使用
new
创建了实例?谢谢您的回复。我不认为我离它看起来那么远。在简化代码和从我最初的问题开始工作的过程中,我搞砸了一些事情。您拥有的和我想要的之间的区别是,我想要创建一个包含每个对象实例的列表。因此,在foreach循环中,我创建了一个对象的新实例(工作正常),但是当我将其添加到列表中时,我得到一个运行时错误,表示该对象为null。具有讽刺意味的是,我可以在“局部变量”窗口中检查对象,发现它不是空的。这可能是因为我在运行时读取了类型。那么您能更正代码示例吗?现在,以下操作永远无法工作:(Type)Activator.CreateInstance(currTyp)