我在初始化静态成员对象时遇到了一些问题。在我的项目中有3个类文件:
Feat
,Class
(RPG风格而非c#类)和Race
。
每个人都有一些静态成员对象,例如Feat.General.MightyBlow
,Race.Dwarf
或Class.Base.Warrior
可以访问MightyBlow.GetType()
- > Feat
,Dwarf.GetType()
- > Race
和Warrior.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
被初始化了。情况并非如此,因为如果我交换这两个成员对象的位置或删除要求,则不会出现错误。
我该如何解决这个问题?请不要告诉我,我必须相应地订购所有专长。
答案 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(或其他格式)可能需要更复杂,因为可能需要多个依赖项等。
但这完全取决于你的要求......