2

我很难表达这个问题,所以我将从一个例子开始:

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;
        }
    }
}

我传入的字典ExoticBirdCollector包含 all ExoticBird,它扩展了Bird,但我每次都必须在GetExoticBird().

是否可以将这些转换一次,也许在构造函数中,这样每次我从 nameToBird_ 得到一只鸟时,它都会是一个ExoticBird?编译器无法知道我ExoticBirds在地图中传递了所有内容,所以除了声明一个单独的字典之外,还有其他方法可以强制执行Dictionary<string, ExoticBird> nameToExoticBird_吗?

我现在正在考虑做的(这似乎不正确)是将 nameToBird_ 设为BirdCollector私有而不是受保护,并将其隐藏在ExoticBirdCollector字符串和ExoticBird.

我最初的问题得到了回答,但我有一个相关的跟进。如果我要求Dictionary<string, ExoticBird>将 传递给在构造函数中接受的新类,Dictionary<string, Bird>我怎么能做到这一点?我怀疑无法进行向下转换,因为对象位于容器内。我可以创建一个新的Dictionary<string, Bird>并循环Dictionary<string, ExoticBird>填充它然后传递它,但这似乎是一个 hack。

4

2 回答 2

4

使您的基类通用并移动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;
    }
}

然后你可以像这样声明它的派生类

public class ExoticBirdCollector : BirdCollector<ExoticBird>
{
    public ExoticBirdCollector(Dictionary<string, ExoticBird> nameToBird)
        : base(nameToBird)
    {
    }
}
于 2013-09-26T15:18:09.480 回答
1

您可以使用泛型和类型约束:

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;
        }
    }
}
于 2013-09-26T15:20:12.450 回答