首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KeyValuePair协方差

KeyValuePair协方差
EN

Stack Overflow用户
提问于 2013-02-16 19:52:59
回答 2查看 1K关注 0票数 12

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

代码语言:javascript
复制
private IDictionary<string, ICollection<string>> foos;

public IEnumerable<KeyValuePair<string, IEnumerable<string>> Foos
{
    get
    {
        return foos;
    }
}

但是KeyValuePair<TKey, TValue>不是协变的。

相反,我必须要做的是:

代码语言:javascript
复制
public IEnumerable<KeyValuePair<string, IEnumerable<string>>> Foos
{
    get
    {
        return foos.Select(x => 
            new KeyValuePair<string, IEnumerable<string>>(x.Key, x.Value));
    }
}

有没有更好/更干净的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-16 22:52:04

不幸的是,KeyValuePair<TKey, TValue>是一个结构体;并且结构体在.NET中不会表现出变化。

当然,您可以通过编写自己的协变Pair接口和一些简单的助手来解决这个问题,以便在KeyValuePair序列和自定义Pair接口之间进行转换。这将允许您执行以下操作:

代码语言:javascript
复制
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>>();

下面是一些示例代码,可以让您实现这一点:

代码语言:javascript
复制
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;
    }
}
票数 6
EN

Stack Overflow用户

发布于 2013-02-16 21:39:45

不太可能。KVP是一种结构:不是itnerface,而是ValueType。

关于方差的有趣的SO post

我认为强制转换更有性能,所以我更喜欢这样编写代码:

代码语言:javascript
复制
private IDictionary<string, IEnumerable<string>> foos;

public IEnumerable<KeyValuePair<string, IEnumerable<string>> Foos
{
    get
    {
        return foos;
    }
}

在我真正需要的地方把KeyValuePair.Value转换成ICollection。坦率地说,这取决于如何使用foos。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14909973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档