如何解决缺少协与IReadOnlyDictionary的? [英] How to get around lack of covariance with IReadOnlyDictionary?
问题描述
我想揭露与一个只读接口持有对象的只读字典。在内部,字典是可写的,等等都是内(请参阅下面的例子code)的对象。我的问题是IReadOnlyDictionary不支持,因为在这个问题<一所列的理由协变转换href="http://stackoverflow.com/questions/2149589/idictionarytkey-tvalue-in-net-4-not-covariant">here.这意味着我不能暴露我的内部字典作为一个只有一个读。
所以我的问题是,有没有一种有效的方法,以我的内部字典转换为IReadOnlyDictionary,或者一些其他的方式来处理呢?我能想到的选项是:
- 在保持两个内置词典和保持同步。
- 创建一个新的字典访问属性时,和之内。投中的所有对象
- 在内部使用它铸IReadOnly的回NotReadOnly。
1似乎是一个痛苦,2似乎非常低效。 3听起来就像是最有希望的时刻,但仍是丑陋的。难道我有什么其他选择?
公共类ExposesReadOnly
{
私人字典&LT; INT,NotReadOnly&GT; InternalDict {获得;组; }
公共IReadOnlyDictionary&LT; INT,IReadOnly&GT; PublicList
{
得到
{
//这不工作...
返回this.InternalDict;
}
}
//这个类可以在内部修改,但我不希望
//展示这一功能。
私有类NotReadOnly:IReadOnly
{
公共字符串名称{;组; }
}
}
公共接口IReadOnly
{
字符串名称{; }
}
您可以编写自己的只读包装词典,如:
公共类ReadOnlyDictionaryWrapper&LT; TKEY的,TValue,TReadOnlyValue&GT; :IReadOnlyDictionary&LT; TKEY的,TReadOnlyValue&GT;其中,TValue:TReadOnlyValue
{
私人的IDictionary&LT; TKEY的,TValue&GT; _字典;
公共ReadOnlyDictionaryWrapper(IDictionary的&LT; TKEY的,TValue&GT;字典)
{
如果(字典== NULL)抛出新ArgumentNullException(辞海);
_dictionary =字典;
}
公共BOOL的containsKey(TKEY的键){返回_dictionary.ContainsKey(键); }
公开的IEnumerable&LT; TKEY的&GT;键{{返回_dictionary.Keys; }}
公共BOOL TryGetValue(TKEY的钥匙,走出TReadOnlyValue值)
{
TValue伏;
VAR的结果= _dictionary.TryGetValue(重点,走出V);
值= V;
返回结果;
}
公开的IEnumerable&LT; TReadOnlyValue&GT;值{{返回_dictionary.Values.Cast&LT; TReadOnlyValue&GT;(); }}
公共TReadOnlyValue这个[TKEY的关键] {{返回_dictionary [关键]; }}
公众诠释计数{{返回_dictionary.Count; }}
公众的IEnumerator&LT; KeyValuePair&LT; TKEY的,TReadOnlyValue&GT;&GT;的GetEnumerator()
{
返回_dictionary
。选择(X =&gt;新建KeyValuePair&LT; TKEY的,TReadOnlyValue&GT;(x.Key,x.Value))
.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回this.GetEnumerator();
}
}
I'm trying to expose a read-only dictionary that holds objects with a read-only interface. Internally, the dictionary is write-able, and so are the objects within (see below example code). My problem is that IReadOnlyDictionary doesn't support covariant conversions because of the reason outlined in the question here. This means I can't just expose my internal dictionary as a read only one.
So my question is, is there an efficient way to convert my internal dictionary to an IReadOnlyDictionary, or some other way to handle this? The options I can think of are:
- Hold two internal dictionaries and keep them in sync.
- Create a new dictionary when the property is accessed and cast all the objects within.
- Cast the IReadOnly's back to NotReadOnly when using it internally.
1 seems like a pain, 2 seems highly inefficient. 3 sounds like the most promising at the moment, but is still ugly. Do I have any other options?
public class ExposesReadOnly
{
private Dictionary<int, NotReadOnly> InternalDict { get; set; }
public IReadOnlyDictionary<int, IReadOnly> PublicList
{
get
{
// This doesn't work...
return this.InternalDict;
}
}
// This class can be modified internally, but I don't want
// to expose this functionality.
private class NotReadOnly : IReadOnly
{
public string Name { get; set; }
}
}
public interface IReadOnly
{
string Name { get; }
}
You could write your own read-only wrapper for the dictionary, e.g.:
public class ReadOnlyDictionaryWrapper<TKey, TValue, TReadOnlyValue> : IReadOnlyDictionary<TKey, TReadOnlyValue> where TValue : TReadOnlyValue
{
private IDictionary<TKey, TValue> _dictionary;
public ReadOnlyDictionaryWrapper(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null) throw new ArgumentNullException("dictionary");
_dictionary = dictionary;
}
public bool ContainsKey(TKey key) { return _dictionary.ContainsKey(key); }
public IEnumerable<TKey> Keys { get { return _dictionary.Keys; } }
public bool TryGetValue(TKey key, out TReadOnlyValue value)
{
TValue v;
var result = _dictionary.TryGetValue(key, out v);
value = v;
return result;
}
public IEnumerable<TReadOnlyValue> Values { get { return _dictionary.Values.Cast<TReadOnlyValue>(); } }
public TReadOnlyValue this[TKey key] { get { return _dictionary[key]; } }
public int Count { get { return _dictionary.Count; } }
public IEnumerator<KeyValuePair<TKey, TReadOnlyValue>> GetEnumerator()
{
return _dictionary
.Select(x => new KeyValuePair<TKey, TReadOnlyValue>(x.Key, x.Value))
.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
这篇关于如何解决缺少协与IReadOnlyDictionary的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!