在这个例子中有没有更好的方法来模仿协方差?理想情况下,我想做的是:
private IDictionary<string, ICollection<string>> foos;
public IEnumerable<KeyValuePair<string, IEnumerable<string>> Foos
{
get
{
return foos;
}
}但是KeyValuePair<TKey, TValue>不是协变的。
相反,我必须要做的是:
public IEnumerable<KeyValuePair<string, IEnumerable<string>>> Foos
{
get
{
return foos.Select(x =>
new KeyValuePair<string, IEnumerable<string>>(x.Key, x.Value));
}
}有没有更好/更干净的方法?
发布于 2013-02-16 22:52:04
不幸的是,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>>();下面是一些示例代码,可以让您实现这一点:
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;
}
}发布于 2013-02-16 21:39:45
不太可能。KVP是一种结构:不是itnerface,而是ValueType。
关于方差的有趣的SO post。
我认为强制转换更有性能,所以我更喜欢这样编写代码:
private IDictionary<string, IEnumerable<string>> foos;
public IEnumerable<KeyValuePair<string, IEnumerable<string>> Foos
{
get
{
return foos;
}
}在我真正需要的地方把KeyValuePair.Value转换成ICollection。坦率地说,这取决于如何使用foos。
https://stackoverflow.com/questions/14909973
复制相似问题