【发布时间】:2023-03-28 16:04:01
【问题描述】:
我正在尝试创建一个场景或状态管理器,它为每个状态存储一个字典,作为加载或更改程序状态(例如,主菜单状态和游戏状态)的一种方式。我有一堆基类 State 的派生类,它们的变量未包含在基 State 类中。我可以安全地将它们存储在这本词典中吗?我会丢失任何数据吗?如果这不起作用,有什么替代方法可以实现我的目标?
【问题讨论】:
标签: c# dictionary base derived
我正在尝试创建一个场景或状态管理器,它为每个状态存储一个字典,作为加载或更改程序状态(例如,主菜单状态和游戏状态)的一种方式。我有一堆基类 State 的派生类,它们的变量未包含在基 State 类中。我可以安全地将它们存储在这本词典中吗?我会丢失任何数据吗?如果这不起作用,有什么替代方法可以实现我的目标?
【问题讨论】:
标签: c# dictionary base derived
这似乎是您可以轻松测试自己的东西。但只是为了好玩,假设你有一个像这样的基类:
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;
}
}
然后你可以像这样创建一个设置:
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);
现在您可以运行一个小测试来查看是否有任何信息丢失:
foreach (Base value in dictionary.Values)
{
Console.WriteLine(value.ToString());
}
如您所见,不仅调用了正确的覆盖ToString(),而且它还具有Description 属性的正确值。所以不,你不会“失去”任何东西。但是只要是base类型,就只能直接访问base属性。
顺便说一句。您还可以检查一个值是否真的是is 某个派生类型:
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 并检查空值,您可以“安全地”(即,例如,没有由直接转换引起的异常)获取“完整”派生类型中的值,您可以在其中再次访问所有附加属性:
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.
}
}
【讨论】: