IDictionary的<,>逆变?逆变、IDictionary、LT、GT

2023-09-04 02:38:33 作者:心葬深海颠沛流离怎能不伤

我有在外部类中的下列方法

I have the following method in an external class

public static void DoStuffWithAnimals(IDictionary<string, Animal> animals)

在我的呼唤code,我已经有一个词典&LT;字符串,狮GT; 的对象,但我无法通过这个作为该方法的参数。因此,一个的IDictionary&LT;,&GT; 不是逆变?我看不出有任何理由为什么这不应该工作。

In my calling code, I already have a Dictionary<string, Lion> object, but I can't pass this in as this method's argument. So a IDictionary<,> isn't contravariant? I can't see any reason why this shouldn't work.

唯一的解决办法我能想到的是:

The only solution I can think of is:

var animals = new Dictionary<string, Animal>();

foreach(var kvp in lions) {
    animals.Add(kvp.Key, kvp.Value);
}

请问有没有办法通过这本词典进入这个方法,而无需创建同一对象的新字典吗?

Is there no way to pass this dictionary into this method, without having to create a new dictionary of the same objects?

编辑:

由于这是我的方法,我知道,我是从字典中使用的唯一成员是吸气TValue这个[TKEY的关键] ,这是一个成员的IDictionary&LT; TKEY的,TValue&GT; ,所以在这种情况下,我无法用一个更广泛类型的参数

As it's my method, I know that the only member I'm using from the dictionary is the getter of TValue this[TKey key], which is a member of IDictionary<TKey, TValue>, so in this scenario, I'm unable to use a 'wider' type for the parameter.

推荐答案

解决方案明智的,你可以做这样的事情,只是传递一个访问,而不是:

Solution wise you could do something like this, just pass in an accessor instead:

    public static void DoStuffWithAnimals(Func<string, Animal> getAnimal)
    {
    }

    var dicLions = new Dictionary<string, Lion>();
    DoStuffWithAnimals(s => dicLions[s]);

显然,这很可能是一个有点简单为您的需求,但如果你只需要一对夫妇的字典方法是pretty的容易拿到的地方。

Obviously that is likely to be a bit simple for your needs, but if you only need a couple of the dictionary methods it's pretty easy to get that in place.

这是另一种方式,让您在动物之间有点code再利用:

This is another way that gives you a bit of code re-use between your animals:

    public class Accessor<T> : IAnimalAccessor where T : Animal
    {
        private readonly Dictionary<string, T> _dict;

        public Accessor(Dictionary<string, T> dict)
        {
            _dict = dict;
        }

        public Animal GetItem(String key)
        {
            return _dict[key];
        }
    }

    public interface IAnimalAccessor
    {
        Animal GetItem(string key);
    }

    public static void DoStuffWithAnimals(IAnimalAccessor getAnimal)
    {
    }

    var dicLions = new Dictionary<string, Lion>();
    var accessor = new Accessor<Lion>(dicLions);
    DoStuffWithAnimals(accessor);