2010-04-07 1 views
0

J'ai pensé à la solution ci-dessous parce que la collection est très très petite. Mais que faire si c'était grand?comment faire accesseur pour le dictionnaire d'une manière qui a retourné Dictionnaire ne peut pas être modifié C#/2.0

private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>(); 

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

avec la liste que vous pouvez faire:

public class MyClass 
{ 
    private List<int> _items = new List<int>(); 

    public IList<int> Items 
    { 
     get { return _items.AsReadOnly(); } 
    } 
} 

Ce serait bien!

Merci à l'avance, Cheers & BR - Matti

maintenant, quand je pense que les OBJETS EN COLLECTION SONT Heap. Donc, ma solution n'empêche pas l'appelant de les modifier !!! CAUSE DEUX DIALOGUES CONTIENNENT DES REFERENCES A UN MEME OBJET. Cela s'applique-t-il à la liste EXEMPLE CI-DESSUS?

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

alors comment rendre cela immuable ??

+0

double possible de http://stackoverflow.com/questions/35002/does-c-have-a-way-of-giving-me-an-immutable-dictionary –

+0

Ignorer mon vote proche comme du pliquer. En relecture, la question n'est pas tout à fait la même. Pardon. –

Répondre

4

Il n'est pas difficile de rouler votre propre classe d'emballage ReadOnlyDictionary<K,V>. Quelque chose comme ceci:

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 
} 

Si vous utilisez C# 3 ou plus tard, alors vous pourriez taquage une AsReadOnly méthode d'extension correspondant aussi:

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

Et puis retourner l'emballage en lecture seule à partir votre propriété:

// in C#2 
return new ReadOnlyDictionary<string, OfTable>(_folderData); 

// in C#3 or later 
return _folderData.AsReadOnly(); 
+0

merci! Oui c'est vrai. beaucoup de code ... j'ai vu une implémentation similaire ici dans StackOverflow. Je vous ai donné 1, mais faire un emballage n'est pas ce que je veux. désolé d'être difficile. Si personne ne peut répondre avec un code plus court, je l'accepte. acclamations mate! –

+0

@matti: Oui beaucoup de code, mais voir autre réponse: ceci est maintenant fait pour vous dans le cadre, et même dans les versions downlevel c'est un code entièrement réutilisable, donc vous avez seulement besoin de l'écrire une fois. – Richard

+0

est un problème: les objets contenus peuvent être modifiés. mais il n'y a peut-être rien à faire. il serait bien que la collection et les objets à l'intérieur soient en lecture seule ... je ne crée pas de bibliothèque de code, mais seulement un programme simple, donc tout ceci n'a pas vraiment d'importance. Je veux juste apprendre ... –

1

Utilisez la classe ReadOnlyCollection<T>.

Une instance de la classe générique ReadOnlyCollection est toujours en lecture seule. Une collection qui est en lecture seule est simplement une collection avec un wrapper qui empêche de modifier la collection; par conséquent, si des modifications sont apportées à la collection sous-jacente, la collection en lecture seule reflète ces modifications. Voir Collection pour une version modifiable de cette classe.

--EDIT--

Commander un trivial dictionary wrapper ici. Et A Generic Read-Only Dictionary par Richard Carr.

+1

pas pour le dictionnaire! –

+0

@Matti: Juste pour que cela puisse aider, s'il vous plaît voir mon edit en réponse à votre commentaire. –

Questions connexes