c# c#-4.0 covariance keyvaluepair

c# - Covarianza de KeyValuePair



c#-4.0 covariance (2)

Apenas. KVP es una estructura: no es una interfaz, es de ValueType.

Interesante publicación SO sobre la varianza.

Creo que los moldes son más efectivos, así que prefiero codificar de esta manera:

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

Y lanzar KeyValuePair.Value a ICollection donde realmente lo necesito. Hablando francamente, depende de cómo se usa foos.

¿Hay una mejor manera de imitar la covarianza en este ejemplo? Idealmente me gustaría hacer:

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

Pero KeyValuePair<TKey, TValue> no es covariante.

En cambio, tengo que hacer:

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

¿Hay una manera mejor / más limpia?


Desafortunadamente, KeyValuePair<TKey, TValue> es una estructura; y las estructuras no muestran variación en .NET.

Por supuesto, puede resolver esto escribiendo su propia interfaz de Pair covariante y algunos ayudantes simples para convertir secuencias de KeyValuePair y su interfaz personalizada de Pair . Esto te permitirá hacer:

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>>();

Aquí hay un código de ejemplo que te permitirá lograr esto:

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