Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 成员字段中的多态性,当字段是对象集合时,这些对象也是继承树的一部分_C#_Oop_Inheritance_Polymorphism - Fatal编程技术网

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方法。