问题描述
我试图创建一个场景或状态管理器,为每个状态存储一个词典,以作为加载或更改程序状态(例如主菜单状态和游戏状态)的一种方式.我有一堆基类State的派生类,这些派生类具有未包含在基类State中的变量.我可以安全地将它们存储在此词典中吗?我会丢失任何数据吗?如果这不起作用,实现我的目标的替代方法是什么?
I am trying to create a scene or state manager which stores a Dictionary for each state as a way to load or change the state of the program (for example, a Main Menu state and a Game state). I have a bunch of derived classes of base class State that have variables that are not included in the base State class. Am I able to safely store them in this Dictionary? Will I have any data loss? If this doesn't work, what are alternative methods to achieve my goal?
推荐答案
似乎可以轻松地进行自我测试.但是只是为了好玩,假设您有一个像这样的基类:
This seems like something you could easily test yourself. But just for the fun of it, suppose you have a base class like:
public class Base
{
public string Name
{
get;
set;
}
public override string ToString()
{
return Name;
}
}
以及类似的派生类:
public class Derived : Base
{
public string Description
{
get;
set;
}
public override string ToString()
{
return base.ToString() + " - " + Description;
}
}
然后您可以创建如下设置:
Then you can create a setup like this:
Base baseObject = new Base{ Name = "Base"};
Derived derivedObject = new Derived { Name = "Derived", Description = "Description" };
Dictionary<int, Base> dictionary = new Dictionary<int, Base>();
dictionary.Add(1, baseObject);
dictionary.Add(2, derivedObject);
现在,您可以进行一些测试以查看是否丢失了任何信息:
Now you can run a little test to see, if any information is lost:
foreach (Base value in dictionary.Values)
{
Console.WriteLine(value.ToString());
}
如您所见,
不仅会调用正确的覆盖的ToString()
,而且对于Description
属性仍然具有正确的值.因此,不,您不会丢失"任何东西.但是,只要它是base
类型,就只能直接访问base
属性.
As you can see, not only is the correct overridden ToString()
called, but it also still has the right value for the Description
property. So no, you don't "lose" anything. But as long as it is a base
type, you can only access the base
properties directly.
顺便说一句.您还可以检查值是否真的is
某些派生类型:
Btw. you can also check, if a value really is
a certain derived type:
foreach (Base value in dictionary.Values)
{
if (value is Derived)
{
Console.WriteLine("{0} is Derived", value.Name);
// trying to access value.Description at this point
// would cause a compiler error "Cannot resolve symbol".
}
else
{
Console.WriteLine("{0} is not Derived", value.Name);
}
}
使用as
并检查是否为空,您可以安全"(即无例外,例如,直接铸造引起的)获取完整"派生类型中的值,在此您可以再次访问所有其他属性:
And with as
and a check for null, you can "safely" (i.e. without exception caused by direct casting for example) get the value in the "full" derived type, where you can access all the additional properties again:
foreach (Base value in dictionary.Values)
{
Derived derived = value as Derived;
if (derived != null)
{
Console.WriteLine("{0} is Derived and has Description: {1}",
derived.Name, derived.Description);
// now that derived actually is of type Derived,
// accessing derived.Description is perfectly fine.
}
}
这篇关于将派生类存储在基类Dictionary中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!