使SortedList只读

时间:2011-05-20 01:39:27

标签: c# dictionary sortedlist

我经常将列表公开为ReadOnlyCollection<T> s,即

public class Class
{
  List<string> list;

  public ReadOnlyCollection<string> TheList
  {
    get { return list.AsReadOnly(); }
  }
}

IDictionary<T,U> SortedList<string, string>等{{1}}执行此操作的最佳方式是什么?

3 个答案:

答案 0 :(得分:4)

public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> sourceDictionary;

    public ICollection<TKey> Keys
    {
        get { return sourceDictionary.Keys; }
    }

    public ICollection<TValue> Values
    {
        get { return sourceDictionary.Values; }
    }

    public TValue this[TKey key]
    {
        get { return sourceDictionary[key]; }
        set { throw new NotSupportedException(); }
    }

    public int Count
    {
        get { return sourceDictionary.Count; }
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    public ReadOnlyDictionary(IDictionary<TKey, TValue> sourceDictionary)
    {
        AssertUtilities.ArgumentNotNull(sourceDictionary, "sourceDictionary");

        this.sourceDictionary = sourceDictionary;
    }

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw new NotSupportedException();
    }

    public bool ContainsKey(TKey key)
    {
        return sourceDictionary.ContainsKey(key);
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw new NotSupportedException();
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return sourceDictionary.TryGetValue(key, out value);
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw new NotSupportedException();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return sourceDictionary.Contains(item);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        sourceDictionary.CopyTo(array, arrayIndex);
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException();
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return sourceDictionary.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)sourceDictionary).GetEnumerator();
    }
}

[编辑] @Simon Buchan和@Cory Nelson指出,对于那些不受支持的方法,最好使用隐式接口实现。相应地更新了代码。

答案 1 :(得分:1)

创建一个ReadOnlyDictionary类,它将IDictionary实现为内部Dictionary实例的包装器。对于修改字典的方法,抛出异常。实现IsReadOnly以返回true。实现所有其他方法以传递给内部Dictionary实例。

答案 2 :(得分:0)

您可以使用标准的 LINQ 方法来实现。

  1. 创建源列表:

     List<String> myList = new List<String>() { "A", "B", "C" };
    
  2. 使用 .ToDictionary linq 扩展方法将您的列表投影到字典中:

     var myDictionary = myList.ToDictionary(listItem => listItem);
    

注意:lambda 表达式从你的列表中偷看一个键(记住该字典只能包含唯一键;否则考虑使用 ILookup 表示列表字典)。

  1. 将你的字典改造成一个 SortedDictionary 实例:

     var mySortedDictionary = new SortedDictionary<string, string>(myDictionary);
    
  2. 将您的排序字典公开为 IReadOnlyDictionary 接口,如下所示:

     public IReadOnlyDictionary MemberDictionary { get; private set; );
    
     // ...somewhere in your constructor or class's initialization method...
     this.MemberDictionary = mySortedDictionary;