将派生的 classes 存储在基础 class 字典中
Storing derived classes in a base class Dictionary
我正在尝试创建一个场景或状态管理器,它为每个状态存储一个字典,作为加载或更改程序状态(例如,主菜单状态和游戏状态)的一种方式。我有一堆派生的 classes of base class State,其中包含未包含在 base State class 中的变量。我可以安全地将它们存储在该词典中吗?我会丢失任何数据吗?如果这不起作用,有哪些替代方法可以实现我的目标?
这似乎是您可以轻松测试的内容。但只是为了好玩,假设你有一个基础 class 像:
public class Base
{
public string Name
{
get;
set;
}
public override string ToString()
{
return Name;
}
}
和派生的 class 如:
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
属性 的正确值。所以不,你没有 "lose" 任何东西。但是只要是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
并检查是否为 null,您可以 "safely"(例如,无一例外地由直接强制转换引起)获取 "full" 派生类型中的值,其中您可以再次访问所有其他属性:
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.
}
}
我正在尝试创建一个场景或状态管理器,它为每个状态存储一个字典,作为加载或更改程序状态(例如,主菜单状态和游戏状态)的一种方式。我有一堆派生的 classes of base class State,其中包含未包含在 base State class 中的变量。我可以安全地将它们存储在该词典中吗?我会丢失任何数据吗?如果这不起作用,有哪些替代方法可以实现我的目标?
这似乎是您可以轻松测试的内容。但只是为了好玩,假设你有一个基础 class 像:
public class Base
{
public string Name
{
get;
set;
}
public override string ToString()
{
return Name;
}
}
和派生的 class 如:
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
属性 的正确值。所以不,你没有 "lose" 任何东西。但是只要是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
并检查是否为 null,您可以 "safely"(例如,无一例外地由直接强制转换引起)获取 "full" 派生类型中的值,其中您可以再次访问所有其他属性:
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.
}
}