2009-03-05 4 views

답변

6

아마 사전 래퍼입니다 자신의 컬렉션의 라인을 따라 뭔가를 구현하는 것이 가장 쉬운 방법 : 마음에 당신의 가치는 읽을 수없는 것이다 유지

public class ReadOnlyDictionary<T, U> 
{ 
    private IDictionary<T, U> BackingStore; 

    public ReadOnlyDictionary<T, U>(IDictionary<T, U> baseDictionary) { 
     this.BackingStore = baseDictionary; 
    } 

    public U this[T index] { get { return BackingStore[index]; } } 

    // provide whatever other methods and/or interfaces you need 
} 
+1

ReadOnlyDictionary를 IDictinary로 상속하는 것을 고려해야합니다. – Sruly

0

열거 형 (IEnumerable)을 노출합니다.

편집 : 예 :

+0

예를 보여주십시오. –

1

만 열거를 제공하려면, 당신은 키/값 쌍 형식의 IEnumerable로 노출 될 수 있습니다. 그러나이 작업은 수행 할 수있는 읽기 전용 작업의 일부를 분명히 제한합니다.

또 다른 옵션은 IDictionary<TKey, TValue>에서 파생 된 새로운 클래스를 작성하여 해당 호출을 실제 랩핑 된 사전에 매핑하여 읽기 전용 액세스를 제공하고 Add과 같은 수정 호출에서 예외를 throw하는 것입니다.

3

을 프로퍼티 게터 (property getter)만으로 사전 (Dictionary)을 래핑 (wrapping)하기 위해 제공된 솔루션; 예 :

ReadOnlyDictionary<int, Employee> readOnlyDict = GetDictionaryHoweverYouLike(); 
ReadOnlyDictionary[5].EmployeeName = "Ooops" 

이렇게하려면 값을 읽기 전용 래퍼 클래스로 묶어야합니다.

+0

값을 복사하지 않는 이유는 무엇입니까? –

+0

값이 복사되는 비용에 따라 다릅니다. –

2

다음은 준비가 된 스 니펫을 필요로하는 모든 사람들을 위해 구현 한 것입니다. 앞에서 언급했듯이이 사전은 읽기 전용이지만 객체는 읽기 전용이 아닙니다!

/// <summary> 
/// Read only wrapper for generics based dictionary. 
/// Only provides lookup retrieval abilities. 
/// </summary> 
/// <typeparam name="TKey"></typeparam> 
/// <typeparam name="TValue"></typeparam> 
public class DictionaryReadOnly<TKey, TValue> : IDictionary<TKey, TValue> 
{ 
    #region Private Members 

    private IDictionary<TKey, TValue> _item; 
    private bool _throwOnWritableAction = false; 

    #endregion 

    #region Constructors 

    /// <summary> 
    /// Constructor requiring the generic dictionary being wrapped. 
    /// </summary> 
    /// <param name="item"></param> 
    public DictionaryReadOnly(IDictionary<TKey, TValue> items) 
    { 
     _throwOnWritableAction = true; 
     _item = items; 
    } 

    /// <summary> 
    /// Constructor requiring the generic dictionary being wrapped. 
    /// </summary> 
    /// <param name="item"></param> 
    public DictionaryReadOnly(IDictionary<TKey, TValue> items, bool throwOnWritableAction) 
    {    
     _throwOnWritableAction = throwOnWritableAction; 
     _item = items; 
    } 
    #endregion 

    #region IDictionary<TKey,TValue> Members 

    /// <summary> 
    /// Number of items in the dictionary. 
    /// </summary> 
    public int Count 
    { 
     get { return _item.Count; } 
    } 

    /// <summary> 
    /// Determine if the underlying collection contains the key. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <returns></returns> 
    public bool ContainsKey(TKey key) 
    { 
     return _item.ContainsKey(key); 
    } 

    /// <summary> 
    /// Returns the value associated with the key. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <returns></returns> 
    public TValue this[TKey key] 
    { 
     get { return _item[key]; } 
     set 
     { 
      CheckAndThrow("Set"); 
     } 
    } 

    /// <summary> 
    /// Return keys. 
    /// </summary> 
    public ICollection<TKey> Keys 
    { 
     get { return _item.Keys; } 
    } 

    /// <summary> 
    /// Not-supported. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <param name="value"></param> 
    public void Add(TKey key, TValue value) 
    { 
     CheckAndThrow("Add"); 
    } 

    /// <summary> 
    /// Not-supported. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <returns></returns> 
    public bool Remove(TKey key) 
    { 
     CheckAndThrow("Remove"); 
     return false; 
    } 

    /// <summary> 
    /// Try to get the value. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <param name="value"></param> 
    /// <returns></returns> 
    public bool TryGetValue(TKey key, out TValue value) 
    { 
     value = default(TValue); 

     if (_item.ContainsKey(key)) 
     { 
      value = _item[key]; 
      return true; 
     } 
     return false; 
    } 

    /// <summary> 
    /// Get the values. 
    /// </summary> 
    public ICollection<TValue> Values 
    { 
     get { return _item.Values; } 
    } 

    #endregion 

    #region ICollection<KeyValuePair<TKey,TValue>> Members 

    /// <summary> 
    /// Not-supported. 
    /// </summary> 
    /// <param name="item"></param> 
    public void Add(KeyValuePair<TKey, TValue> item) 
    { 
     CheckAndThrow("Add"); 
    } 

    /// <summary> 
    /// Not-Supported. 
    /// </summary> 
    public void Clear() 
    { 
     CheckAndThrow("Clear"); 
    } 

    /// <summary> 
    /// Determine whether key value pair is in dictionary. 
    /// </summary> 
    /// <param name="item"></param> 
    /// <returns></returns> 
    public bool Contains(KeyValuePair<TKey, TValue> item) 
    { 
     return _item.Contains(item); 
    } 

    /// <summary> 
    /// Copy items to the array. 
    /// </summary> 
    /// <param name="array"></param> 
    /// <param name="arrayIndex"></param> 
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) 
    { 
     this._item.CopyTo(array, arrayIndex); 
    } 

    /// <summary> 
    /// Indicate read-only 
    /// </summary> 
    public bool IsReadOnly 
    { 
     get { return true; } 
    } 

    /// <summary> 
    /// Non-supported action. 
    /// </summary> 
    /// <param name="item"></param> 
    /// <returns></returns> 
    public bool Remove(KeyValuePair<TKey, TValue> item) 
    { 
     CheckAndThrow("Remove"); 
     return false; 
    } 

    #endregion 

    #region IEnumerable<KeyValuePair<TKey,TValue>> Members 
    /// <summary> 
    /// Get the enumerator. 
    /// </summary> 
    /// <returns></returns> 
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
    { 
     return _item.GetEnumerator(); 
    } 

    #endregion 

    #region IEnumerable Members 
    /// <summary> 
    /// Get the enumerator. 
    /// </summary> 
    /// <returns></returns> 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return _item.GetEnumerator(); 
    } 

    #endregion 

    /// <summary> 
    /// Check and thrown based on flag. 
    /// </summary> 
    /// <param name="action"></param> 
    void CheckAndThrow(string action) 
    { 
     if (_throwOnWritableAction) 
      throw new InvalidOperationException("Can not perform action : " + action + " on this read-only collection."); 
    } 
} 
관련 문제