加载类中的静态字段

问题描述 投票:0回答:3

我有一类带有一些静态污秽的东西。初始化它们后,会将其添加到字典中。当程序第二次启动时,它将尝试访问Dictionary的内容,但是由于我尚未访问该类中的任何filds(Dictionary在另一个字典中),因此找不到它们。

我已经了解到,当我访问静态字段时,它们会初始化,但是还有其他方法可以在不调用任何方法或字段的情况下初始化它们,而没有其他原因,然后将它们初始化一次?

-------------------这里是一些代码:

Resource.cs

public class Resource : InventoryItem
{
    public const int IDBase = 1000000;

    private Resource(int id) : base(IDBase + id) { }

    public static Resource Hydrogen { get; } = new Resource(1); // H
    public static Resource Helium { get; } = new Resource(2); // He
    public static Resource Lithium { get; } = new Resource(3); // Li
    public static Resource Beryllium { get; } = new Resource(4); // Be
    public static Resource Boron { get; } = new Resource(5); // B
    public static Resource Carbon { get; } = new Resource(6); // C
    public static Resource Nitrogen { get; } = new Resource(7); // N
    public static Resource Oxygen { get; } = new Resource(8); // O
    // and all the other elements....
    }
}

InventoryItem.cs

public abstract class InventoryItem
{
    public int ID { get; }

    private static readonly Dictionary<int, InventoryItem> idList = new Dictionary<int, InventoryItem>();

    public InventoryItem(int id)
    {
        ID = id;
        idList[id] = this;
    }

    public static InventoryItem GetFromID(int id)
    {
        return idList[id];
    }
}

当我从资源类访问任何内容之前使用InventoryItem.GetFromID(int id)时,词典为空,无法找到任何内容。如果我在字典中访问任何资源之前。

c# static initialization
3个回答
1
投票

由于类中的静态字段仅在首次使用该类时才被初始化,因此您必须以某种方式强制执行此初始化,例如通过调用Resource中的任何静态方法。

示例:

在资源中,添加

public static void Initialize()
{
    // can be left empty; just forces the static fields to be initialized
}

以及您项目中的其他地方

Resource.Initialize();

0
投票

或者,您可以在静态构造函数中初始化它们。就像默认构造函数一样,它是静态的。它类似于Java的static { ... }

public class Resource : InventoryItem
{
    public const int IDBase = 1000000;

    public static Resource Hydrogen { get; }
    public static Resource Helium { get; }
    public static Resource Lithium { get; }
    // ...

    private Resource(int id) : base(IDBase + id)
    {
    }

    private static Resource()
    {
        Hydrogen = new Resource(1);
        Helium = new Resource(2);
        Lithium = new Resource(3);
        // etc...
    }
}

注意-我实际上没有尝试过,但是我认为它可能有效。


0
投票

静态字段和属性都是在类型构造函数中初始化的,而不管您如何编写,因此两者:

static Resource()
{
    Hydrogen = new Resource(1);
}

Hydrogen { get; } = new Resource(1);

是同一件事,唯一的区别是初始化顺序,它也允许您调用静态函数,但是在OP的情况下,它实际上没有任何区别,这就是为什么pamcevoy的答案不起作用的原因。

Klaus提供了一种有效的处理方式,并且可以正常工作,只是您需要在您的Initialize之前至少调用一次GetFromID方法,以初始化所有Resource类的静态属性,例如:

Resource.Initialize();

InventoryItem.GetFromID(id);

您的最后一个选择是进行方法屏蔽,基本上将与Resource运算符相同的GetFromID方法添加到new类中,然后通过GetFromID类调用Resource,例如

public class Resource : InventoryItem
{
    public static new InventoryItem GetFromID(int id)
    {
        return InventoryItem.GetFromID(id);
    }   
}

但是要知道方法重影与重写方法不同,因此,如果您调用InventoryItem.GetFromID,就不会调用Resource.GetFromID。这将消除在启动时调用Initialize类中单独的Resource方法的需要,但是,它将迫使您至少一次通过GetFromID类调用Resource

更新:归根结底,初始化静态字段/属性的唯一方法是访问所述类中的一件事或另一件事。

© www.soinside.com 2019 - 2024. All rights reserved.