C# 成员字段中的多态性,当字段是对象集合时,这些对象也是继承树的一部分
我很难清楚地表达这个问题,所以我将从一个例子开始:C# 成员字段中的多态性,当字段是对象集合时,这些对象也是继承树的一部分,c#,oop,inheritance,polymorphism,C#,Oop,Inheritance,Polymorphism,我很难清楚地表达这个问题,所以我将从一个例子开始: public class BirdCollector { protected Dictionary<string, Bird> nameToBird_; public BirdCollector(Dictionary<string, Bird> nameToBird) { nameToBird_ = nameToBird; } } public class Exotic
public class BirdCollector
{
protected Dictionary<string, Bird> nameToBird_;
public BirdCollector(Dictionary<string, Bird> nameToBird)
{
nameToBird_ = nameToBird;
}
}
public class ExoticBirdCollector
{
public ExoticBirdCollector(Dictionary<string, Bird> nameToBird)
: base(nameToBird)
{ }
public ExoticBird GetExoticBird(string name)
{
Bird bird;
if(nameToBird_.TryGetValue(name, out bird))
{
return (ExoticBird)bird;
}
else
{
// handle error
return null;
}
}
}
公共类BirdCollector
{
受保护的字典名Tobird;
公共鸟类采集器(字典名称Tobird)
{
nameToBird=nameToBird;
}
}
公共类ExoticBirdCollector
{
公共ExoticBirdCollector(字典名ToBird)
:base(nameToBird)
{ }
public ExoticBird GetExoticBird(字符串名称)
{
鸟;
if(名称鸟_uyGetValue(名称鸟)
{
返回鸟;
}
其他的
{
//处理错误
返回null;
}
}
}
我正在传递到ExoticBirdCollector
的字典包含所有ExoticBird
,它扩展了Bird
,但我每次都必须在GetExoticBird()
中重新转换它们
有没有可能在构造器中强制转换一次,这样每次我从nameToBird得到一只鸟时,它都会是一只ExoticBird
?编译器无法知道我正在传递映射中的所有ExoticBirds
,因此除了声明一个单独的字典(例如字典名toexoticbirds
)之外,还有其他方法可以强制执行吗
我现在考虑做的(这似乎不正确)是在BirdCollector
中把名字命名为bird_uu而不是protected,并将它隐藏在ExoticBirdCollector
字符串和ExoticBird
字典中
我最初的问题得到了回答,但我有一个相关的后续行动。如果我要求将
字典
传递到构造函数中接受字典
的新类中,我该如何实现?我怀疑无法进行向下投射,因为对象位于容器内。我可以创建一个新的字典
并循环通过字典
来填充它,然后传递它,但这看起来像是一个黑客操作。使基类成为泛型并移动GetBird
方法
public class BirdCollector<T> where T : Bird
{
readonly Dictionary<string, T> nameToBird_;
public BirdCollector(Dictionary<string, T> nameToBird)
{
nameToBird_ = nameToBird;
}
public T GetBird(string name)
{
T bird;
if (nameToBird_.TryGetValue(name, out bird))
{
return bird;
}
// handle error
return null;
}
}
公共类BirdCollector,其中T:Bird
{
只读字典名Tobird_u2;;
公共鸟类采集器(字典名称Tobird)
{
nameToBird=nameToBird;
}
公共T GetBird(字符串名称)
{
T鸟;
if(名称鸟_uyGetValue(名称鸟)
{
返回鸟;
}
//处理错误
返回null;
}
}
然后您可以像这样声明它的派生类
public class ExoticBirdCollector : BirdCollector<ExoticBird>
{
public ExoticBirdCollector(Dictionary<string, ExoticBird> nameToBird)
: base(nameToBird)
{
}
}
公共类ExoticBirdCollector:BirdCollector
{
公共ExoticBirdCollector(字典名ToBird)
:base(nameToBird)
{
}
}
您可以使用泛型和类型约束:
public class Bird
{ }
public class ExoticBird : Bird
{ }
public class BirdCollector<T> where T : Bird
{
protected Dictionary<string, T> nameToBird_;
public BirdCollector(Dictionary<string, T> nameToBird)
{
nameToBird_ = nameToBird;
}
}
public class ExoticBirdCollector : BirdCollector<ExoticBird>
{
public ExoticBirdCollector(Dictionary<string, ExoticBird> nameToBird)
: base(nameToBird)
{ }
public ExoticBird GetExoticBird(string name)
{
ExoticBird bird;
if (nameToBird_.TryGetValue(name, out bird))
{
return bird;
}
else
{
// handle error
return null;
}
}
}
公共类鸟类
{ }
公共类飞鸟:飞鸟
{ }
公共类BirdCollector,其中T:Bird
{
受保护的字典名Tobird;
公共鸟类采集器(字典名称Tobird)
{
nameToBird=nameToBird;
}
}
公共类ExoticBirdCollector:BirdCollector
{
公共ExoticBirdCollector(字典名ToBird)
:base(nameToBird)
{ }
public ExoticBird GetExoticBird(字符串名称)
{
异域鸟;
if(名称鸟_uyGetValue(名称鸟)
{
返回鸟;
}
其他的
{
//处理错误
返回null;
}
}
}
ExoticBird
是否继承自Bird
?是的,我将编辑以提及这一点,谢谢你们。这解决了我无法将字典传递到构造函数的主要问题。我也喜欢通用的GetBird方法。