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

发布于 2024-08-01 22:35:13 字数 1416 浏览 9 评论 0原文

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

类型列表现在是对象类型

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

未将对象引用设置为对象的实例。 
  

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

编辑:更新代码示例

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;

I have a foreach loop that cycles through a list of types and creates an instance of each one. However, when I build, it gives a CS0246 error ("The type or namespace could not be found ... "). Here's a simplified version of the code:

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

Edit: Follow-up question

My foreach loop now looks like this:

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

with Types List now being of type Object

This compiles fine, but when I run it, I get the following:

Object reference not set to an instance of an object.

If I break this up into two lines that first creates an object then adds it to the List, the first line is fine (the object is created successfully), but it gives me the same error message.

Edit: Update code sample

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷情 2024-08-08 22:35:13

您必须初始化变量

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

You must initialize your variables

public static List<IPlugin> Plugins=new List<IPlugin>();
最近可好 2024-08-08 22:35:13

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

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

currType is a variable, not a type variable, so you have to use the non-generic overload:

Object newObj = Activator.CreateInstance(currType);
                                        ^        ^
单身狗的梦 2024-08-08 22:35:13

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

所以你可以这样做:

(SomeType)Activator.CreateInstance<SomeType>;

但你不能这样做:

(currType)Activator.CreateInstance<currType>;

Generics have to be known at compile time. You can't pass in a type that's determined at run time.

So you can do this:

(SomeType)Activator.CreateInstance<SomeType>;

but you can't do this:

(currType)Activator.CreateInstance<currType>;
原谅我要高飞 2024-08-08 22:35:13

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

至于您的后续问题:您正在将 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;
    }
  }

For the follow-up: it seems you are confused by the difference between the concepts 'Generics' and 'Reflection', you might want to read up on both.

As for your followup question: you are casting the result of Activator.CreateInstance to System.Type, while in fact you should be casting to the actual type. If you want to cast back to the actual type, you need additional runtime checking.

Maybe this code can help you understand:

  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;
    }
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文