【问题标题】:Creating a static array with already existing objects in C# [duplicate]在 C# 中使用现有对象创建静态数组 [重复]
【发布时间】:2017-02-25 17:05:24
【问题描述】:

我正在使用静态类作为某种库(也许不是最好的主意,但我真的不知道我在做什么......)并且我有一些带有对象的字段,所以我可以访问它们很容易被名字。但是我仍然需要一个数组,我可以使用一种方法来搜索。

但是当我调用该方法 GetTypeByName("Iron Mine") 它应该返回查看数组并返回 ironMine 对象,但它只是尖叫“对象引用未设置为对象的实例”......我'我显然缺少一些关于静态数组或一般数组的东西,我还没有习惯它们......

public static class IndustryTypes
{
    public static IndustryType[] allTypes = //This is that array that seems to mess things up...
    {
        ironMine, coalMine, aluminiumMine, copperMine, uraniumMine, goldMine,
        quarry, oilWell,
        farm
    };

    public static IndustryType noType;
    public static IndustryType ironMine, coalMine, aluminiumMine, copperMine, uraniumMine, goldMine;
    public static IndustryType quarry, oilWell;
    public static IndustryType farm;

    static IndustryTypes()
    {
        noType = new IndustryType("noType", 0, Color.Red);
        ironMine = new IndustryType("Iron Mine", 50000, Game.color_mine);
        coalMine = new IndustryType("Coal Mine", 40000, Game.color_mine);
        aluminiumMine = new IndustryType("Aluminium Mine", 100000, Game.color_mine);
        copperMine = new IndustryType("Copper Mine", 55000, Game.color_mine);
        uraniumMine = new IndustryType("Uranium Mine", 150000, Game.color_mine);
        goldMine = new IndustryType("Gold Mine", 125000, Game.color_mine);

        quarry = new IndustryType("Quarry", 25000, Game.color_mine);
        oilWell = new IndustryType("Oil Well", 110000, Game.color_oil);
        farm = new IndustryType("Farm", 10000, Game.color_farm);

    }

    public static IndustryType GetTypeByName(string name)
    {
        for (int i = 0; i < allTypes.Length; i++)
        {
            if (name == allTypes[i].name) //This says "Object reference not set to an instance of an object" or something like that...
            {
                return allTypes[i];
            }
        }
        return noType;
    }
}

这都是在一个名为“IndustryTypes”的静态类中,所以我不需要实例化它。

“IndustryType”类是一个非静态类。

问你是否不明白我的意思......我并不真正了解自己,但我会尝试! :D

这是“IndustryType”类:

public class IndustryType
{
    public string name;
    public int cost;
    public Color color;
    public List<Resource> components;
    public List<Resource> products;

    public IndustryType(string _name, int _cost, Color _color)
    {
        name = _name;
        cost = _cost;
        color = _color;
    }
}

非常感谢您抽出宝贵时间!

【问题讨论】:

  • 由于您的集合初始化程序,您的数组正在使用空引用构造。将数组构造移到静态构造函数中。
  • @Svek 我没有复制所有内容,如果你的意思是第一行,那就是数组
  • 你必须使用allTypes = new IndustryType[] { blah blah };
  • 除非你有充分的理由,否则不要使用static。见When to use static classes in C#
  • 我同意他应该删除这个静态类。但是他应该保留静态字段(由属性封装)并将它们移动到它们所属的非多元化类中。一个名为 AllTypes 的静态属性肯定是有意义的(尽管最好使用一个列表来实现,该列表具有由类的实例构造函数添加到它的项目)。单例是最常被鄙视的反模式之一。它们有其用途,但这是一个笼统的说法。静态类对于实用程序类(如 IO 类)非常有用,但也可用于通过嵌套静态类进行缓存。

标签: c#


【解决方案1】:

IndustryTypes类的静态构造函数在所有静态字段初始化后执行。所以,目前,当它被执行时:

public static IndustryType[] allTypes = //This is that array that seems to mess things up...
{
    ironMine, coalMine, aluminiumMine, copperMine, uraniumMine, goldMine,
    quarry, oilWell,
    farm
};

ironMine 等所有字段仍未初始化并指向 null。

解决方案:将字段的初始化从静态构造函数移到声明本身。另请注意,初始化程序是按文本顺序执行的,因此您必须在所有其他字段之后最后声明数组。

public static class IndustryTypes
{
    public static IndustryType noType = new IndustryType("noType", 0, Color.Red);
    public static IndustryType ironMine = new IndustryType("Iron Mine", 50000, Game.color_mine);
    public static IndustryType coalMine = new IndustryType("Coal Mine", 40000, Game.color_mine);
    public static IndustryType aluminiumMine = new IndustryType("Aluminium Mine", 100000, Game.color_mine);
    public static IndustryType copperMine = new IndustryType("Copper Mine", 55000, Game.color_mine);
    public static IndustryType uraniumMine = new IndustryType("Uranium Mine", 150000, Game.color_mine);
    public static IndustryType goldMine = new IndustryType("Gold Mine", 125000, Game.color_mine);
    public static IndustryType quarry = new IndustryType("Quarry", 25000, Game.color_mine);
    public static IndustryType oilWell = new IndustryType("Oil Well", 110000, Game.color_oil);
    public static IndustryType farm = new IndustryType("Farm", 10000, Game.color_farm);

    public static IndustryType[] allTypes = {
        IndustryTypes.ironMine,
        IndustryTypes.coalMine,
        IndustryTypes.aluminiumMine,
        IndustryTypes.copperMine,
        IndustryTypes.uraniumMine,
        IndustryTypes.goldMine,
        IndustryTypes.quarry,
        IndustryTypes.oilWell,
        IndustryTypes.farm
    };
}

【讨论】:

    【解决方案2】:

    您将数组定义为空引用数组。将数组构造移动到静态构造函数的末尾。

    public static IndustryType[] allTypes;
    
    public static IndustryType noType; 
    public static IndustryType ironMine, coalMine, aluminiumMine, copperMine, uraniumMine, goldMine; 
    public static IndustryType quarry, oilWell; 
    public static IndustryType farm;
    
    static IndustryTypes() {
        noType = new IndustryType("noType", 0, Color.Red);
        ironMine = new IndustryType("Iron Mine", 50000, Game.color_mine);
        coalMine = new IndustryType("Coal Mine", 40000, Game.color_mine);
        aluminiumMine = new IndustryType("Aluminium Mine", 100000, Game.color_mine);
        copperMine = new IndustryType("Copper Mine", 55000, Game.color_mine);
        uraniumMine = new IndustryType("Uranium Mine", 150000, Game.color_mine);
        goldMine = new IndustryType("Gold Mine", 125000, Game.color_mine);
    
        quarry = new IndustryType("Quarry", 25000, Game.color_mine);
        oilWell = new IndustryType("Oil Well", 110000, Game.color_oil);
        farm = new IndustryType("Farm", 10000, Game.color_farm);
    
    
       allTypes = new [] {
        ironMine, coalMine, aluminiumMine, copperMine, uraniumMine, goldMine,
        quarry, oilWell, farm }; 
    }
    

    如果您永远不会直接访问这些公共字段,即通过IndustryTypes.goldMine,那么您可以删除它们并将它们一次全部分配给不带字段的数组。

    allTypes=new[] { 
              new IndustryType("noType", 0, Color.Red), 
              new IndustryType("Iron Mine", 50000, Game.color_mine), 
              new IndustryType("Coal Mine", 40000, Game.color_mine), 
              new IndustryType("Aluminium Mine", 100000, Game.color_mine), 
              new IndustryType("Copper Mine", 55000, Game.color_mine), 
              new IndustryType("Uranium Mine", 150000, Game.color_mine), 
              new IndustryType("Gold Mine", 125000, Game.color_mine), 
              new IndustryType("Quarry", 25000, Game.color_mine), 
              new IndustryType("Oil Well", 110000, Game.color_oil), 
              new IndustryType("Farm", 10000, Game.color_farm) 
    };
    

    如果可以的话,我建议在字段上使用公共属性并将其全部移入 IndustryType 类(不是复数)

    注意您的数组是公开的。它不是只读的,它的元素可以更改。您最好将其封装在作为IReadOnlyXXX 接口之一公开的属性后面。否则有人可以在您不知情/未经您许可的情况下执行IndustryTypes.allTypes[0]=null;(或者更糟糕的是,将其设置为新的IndustryType 实例)。

    【讨论】:

    • 谢谢,但我大部分时间都会直接访问它们?
    • 想我还是会指出来以防万一
    • 在最后查看我添加的注释
    • 你的最后一条注释:这是真的......但我写的只是我自己的一个新手项目,如果我想做任何正式的事情,我还有很多东西要学:D
    猜你喜欢
    • 2014-01-30
    • 2013-06-28
    • 1970-01-01
    • 2017-08-26
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多