KeyValuePair协方差

Ben*_*ter 10 c# covariance c#-4.0 keyvaluepair

在这个例子中是否有更好的模仿协方差的方法?理想情况下我想做:

private IDictionary<string, ICollection<string>> foos;

public IEnumerable<KeyValuePair<string, IEnumerable<string>> Foos
{
    get
    {
        return foos;
    }
}
Run Code Online (Sandbox Code Playgroud)

KeyValuePair<TKey, TValue>不是协变的.

相反,我必须这样做:

public IEnumerable<KeyValuePair<string, IEnumerable<string>>> Foos
{
    get
    {
        return foos.Select(x => 
            new KeyValuePair<string, IEnumerable<string>>(x.Key, x.Value));
    }
}
Run Code Online (Sandbox Code Playgroud)

有更好/更清洁的方式吗?

Ani*_*Ani 6

不幸的是,KeyValuePair<TKey, TValue>是一个结构; 和结构在.NET中不会出现差异.

您当然可以通过编写自己的协变Pair接口和一些简单的帮助程序来解决这个问题,以便在KeyValuePair自定义Pair接口的序列之间进行转换.这将让你做到:

var dict = new Dictionary<string, ICollection<string>>();

// Notice that you can "weaken" both the key and the value.
var dictView = dict.GetCovariantView()
                   .CastPairs<object, IEnumerable<string>>();
Run Code Online (Sandbox Code Playgroud)

这里有一些示例代码可以让您实现此目的:

public interface IPair<out TKey, out TValue>
{
    TKey Key { get; }
    TValue Value { get; }
}

public class Pair<TKey, TValue> : IPair<TKey, TValue>
{
    public TKey Key { get; private set; }
    public TValue Value { get; private set; }

    public Pair(TKey key, TValue value)
    {
        Key = key;
        Value = value;
    }

    public Pair(KeyValuePair<TKey, TValue> pair)
        : this(pair.Key, pair.Value) {   }
}

public static class PairSequenceExtensions
{
    public static IEnumerable<IPair<TKey, TValue>> GetCovariantView<TKey, TValue>
            (this IEnumerable<KeyValuePair<TKey, TValue>> source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        return source.Select(pair => new Pair<TKey, TValue>(pair));
    }

    public static IEnumerable<IPair<TKey, TValue>> CastPairs<TKey, TValue>
        (this IEnumerable<IPair<TKey, TValue>> source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        return source;
    }
}
Run Code Online (Sandbox Code Playgroud)