我在初始化静态成员对象时遇到了一些问题。在我的项目中有 3 个类文件:
Feat
、Class
(RPG 风格的非 c# 类)和Race
.
它们中的每一个都有一些静态成员对象,例如 Feat.General.MightyBlow
、Race.Dwarf
或 Class.Base.Warrior
可以访问这些对象,同时MightyBlow.GetType()
-> Feat
、 Dwarf.GetType()
-> Race
和 Warrior.GetType()
-> Class
访问。一项壮举可以取决于其他壮举、职业和种族,阶级和种族也是如此。这 3 个类别中的每一个都不是由真正的类/壮举/种族引用的,而是由一个可以在字典中查找的名称字符串引用的,例如: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:对象引用未设置为对象的实例 壮举+熟练度..CCTOR ()
我认为在初始化ArmorHeavy
C# 时达到了调用 ArmorLight.GetName
的点,现在跳转到ArmorLight
的初始化并在初始化ArmorLight
后完成ArmorHeavy
。事实并非如此,因为如果我交换这两个成员对象的位置或删除要求,就不会有错误。
我该如何解决这个问题?请不要告诉我我必须相应地订购所有壮举。
您必须这样做,无法访问空引用的成员。
但是通过使用静态构造函数可以更清楚地说明这一点:
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
中,类名是类的真实名称,这些属性在:)
另一种选择是将它们Lazy
但对于仅仅避免正确的初始化顺序来说,这可能太麻烦了。
由于有很多这样的东西,因此将这些类型的属性和依赖项移到代码之外(例如移动到 XML 中)可能是个好主意:
<Feats>
<Feat Name="Light" />
<Feat Name="Heavy" Requires="Light" />
</Feats>
然后编写一些代码来读出 XML 并初始化对象。
您的实际XML(或其他格式)可能需要更复杂,因为可能需要多个依赖项等。
但这当然取决于您的要求...