代码之家  ›  专栏  ›  技术社区  ›  char m

如何在返回的字典不能更改的情况下为字典创建访问器C#/2.0

  •  0
  • char m  · 技术社区  · 15 年前

    我想到了下面的解决方案,因为收藏量非常小。但是如果它很大呢?

    private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>();
    
    public Dictionary<string, OfTable> FolderData
    {
        get { return new Dictionary<string,OfTable>(_folderData); }
    }
    

    public class MyClass
    {
        private List<int> _items = new List<int>();
    
        public IList<int> Items
        {
            get { return _items.AsReadOnly(); }
        }
    }
    

    那太好了!

    提前谢谢,干杯;BR-马蒂

    class OfTable
    {
        private int _table;
        private List<int> _classes;
        private string _label;
    
        public OfTable()
        {
            _classes = new List<int>();
        }
    
        public int Table
        {
            get { return _table; }
            set { _table = value; }
        }
    
        public List<int> Classes
        {
            get { return _classes; }
            set { _classes = value; }
        }
    
        public string Label
        {
            get { return _label; }
            set { _label = value; }
        }
    }
    

    那么,如何使这个不变??

    2 回复  |  直到 15 年前
        1
  •  4
  •   LukeH    14 年前

    自己动手并不难 ReadOnlyDictionary<K,V>

    public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    {
        private readonly IDictionary<TKey, TValue> _dictionary;
    
        public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
    
            _dictionary = dictionary;
        }
    
        public bool ContainsKey(TKey key)
        {
            return _dictionary.ContainsKey(key);
        }
    
        public int Count
        {
            get { return _dictionary.Count; }
        }
    
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return _dictionary.GetEnumerator();
        }
    
        public ICollection<TKey> Keys
        {
            get { return _dictionary.Keys; }
        }
    
        public bool TryGetValue(TKey key, out TValue value)
        {
            return _dictionary.TryGetValue(key, out value);
        }
    
        public ICollection<TValue> Values
        {
            get { return _dictionary.Values; }
        }
    
        public TValue this[TKey key]    // Item
        {
            get { return _dictionary[key]; }
        }
    
        #region IDictionary<TKey, TValue> Explicit Interface Implementation
    
        void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
        {
            throw new NotSupportedException("Dictionary is read-only.");
        }
    
        bool IDictionary<TKey, TValue>.Remove(TKey key)
        {
            throw new NotSupportedException("Dictionary is read-only.");
        }
    
        TValue IDictionary<TKey, TValue>.this[TKey key]    // Item
        {
            get { return _dictionary[key]; }
            set { throw new NotSupportedException("Dictionary is read-only."); }
        }
    
        #endregion
    
        #region ICollection<T> Explicit Interface Implementation
    
        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException("Collection is read-only.");
        }
    
        void ICollection<KeyValuePair<TKey, TValue>>.Clear()
        {
            throw new NotSupportedException("Collection is read-only.");
        }
    
        bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
        {
            return _dictionary.Contains(item);
        }
    
        void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            _dictionary.CopyTo(array, arrayIndex);
        }
    
        bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
        {
            get { return true; }
        }
    
        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException("Collection is read-only.");
        }
    
        #endregion
    
        #region IEnumerable Explicit Interface Implementation
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)_dictionary).GetEnumerator();
        }
    
        #endregion
    }
    

    如果你使用的是C#3或更高版本,那么你可以找到一个匹配的 AsReadOnly 扩展方法:

    public static class ReadOnlyDictionaryHelper
    {
        public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
        {
            var temp = dictionary as ReadOnlyDictionary<TKey, TValue>;
            return temp ?? new ReadOnlyDictionary<TKey, TValue>(dictionary);
        }
    }
    

    然后从属性返回只读包装器:

    // in C#2
    return new ReadOnlyDictionary<string, OfTable>(_folderData);
    
    // in C#3 or later
    return _folderData.AsReadOnly();
    
        2
  •  1
  •   Community CDub    8 年前

    使用 ReadOnlyCollection<T>

    ReadOnlyCollection泛型类的实例始终是只读的。只读的集合只是一个带有包装器的集合,包装器阻止修改集合;因此,如果对基础集合进行了更改,则只读集合将反映这些更改。有关此类的可修改版本,请参见集合。

    --编辑--

    trivial dictionary wrapper 在这里。以及 A Generic Read-Only Dictionary 理查德·卡尔。