静态成员对象的初始化c#

时间:2014-04-02 18:01:32

标签: c# static initialization static-members

我在初始化静态成员对象时遇到了一些问题。在我的项目中有3个类文件:

FeatClass(RPG风格而非c#类)和Race

每个人都有一些静态成员对象,例如Feat.General.MightyBlowRace.DwarfClass.Base.Warrior可以访问MightyBlow.GetType() - > FeatDwarf.GetType() - > RaceWarrior.GetType() - > Class。一项壮举可以依赖于其他专长,课程和比赛,同样适用于课程和比赛。这三个类别中的每一个都不是由真正的类/专长/种族引用,而是由名称字符串引用,可以在字典中查找,如:Class someClass = Class.Implemented[someClassesName]

一些最小的例子:

public static Feat ArmorHeavy = new Feat(
    "ArmorHeavy",
    Req.Feats(ArmorLight.GetName),
);

public static Feat ArmorLight = new Feat(
    "ArmorLight",
    Req.Feats(),
);

正如您所看到的,ArmorHeavy首先需要ArmorLight,并且该要求仅由ArmorLight的名称标识(只是字符串“ArmorLight”)。

我没有编译器错误,但在运行时我收到以下错误

  

NullReferenceException:未将对象引用设置为对象的实例   Feat + Proficiency..cctor()

我认为在初始化ArmorHeavy时,C#到达ArmorLight.GetName被调用的点,现在跳转到ArmorLight的初始化并在ArmorHeavy之后完成ArmorLight被初始化了。情况并非如此,因为如果我交换这两个成员对象的位置或删除要求,则不会出现错误。

我该如何解决这个问题?请不要告诉我,我必须相应地订购所有专长。

1 个答案:

答案 0 :(得分:6)

您必须完全这样做,无法访问空引用的成员。

但是使用static constructor

可以更清楚
public static Feat ArmorHeavy;
public static Feat ArmorLight;

static ClassName()
{
    ArmorLight = new Feat("ArmorLight", Req.Feats());
    ArmorHeavy = new Feat("ArmorHeavy", Req.Feats(ArmorLight.GetName));
}

请注意,在static ClassName中,ClassName是类的真实名称,这些属性在以下位置定义:)

另一种选择是将它们设为Lazy,但仅仅避免正确的初始化顺序可能会有太多麻烦。

由于有很多这些东西,所以将这些属性和依赖项移到代码之外可能是个好主意,例如转换为XML:

<Feats>
  <Feat Name="Light" />
  <Feat Name="Heavy" Requires="Light" />
</Feats>

然后编写一些代码来读出XML并初始化对象。

您的实际XML(或其他格式)可能需要更复杂,因为可能需要多个依赖项等。

但这完全取决于你的要求......