Question

J'ai une classe en C # qui contient un dictionnaire, que je veux créer et faire en sorte que rien ajouté, modifié ou retiré de ce dictionnaire aussi longtemps que la classe qui contient elle existe.

readonly n'aide vraiment, une fois que je l'ai testé et vu que je peux ajouter des éléments après. Juste par exemple, j'ai créé un exemple:

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public void Add(int key, int value)
    {
        myDictionary.Add(key, value);
    }

}

Je veux la méthode Add de ne pas travailler. Si possible, je veux pas même compiler. Toutes les suggestions?

En fait, je suis inquiet car il est le code qui sera ouvert pour beaucoup de gens à changer. Donc, même si je cache la méthode Add, il sera possible pour quelqu'un de « innocemment » créer une méthode qui ajoute une clé ou supprimer une autre. Je veux que les gens regardent et savent qu'ils ne devraient pas changer le dictionnaire de toutes les façons. Tout comme je l'ai avec une variable const.

Était-ce utile?

La solution

Il n'y a rien dans le .NET Framework pour vous aider, mais cette post donne une assez bonne mise en œuvre d'un générique en C ReadOnlyDictionary #. Il implémente toutes les interfaces vous pouvez vous attendre à (IDictionary, ICollection, IEnumerable, etc.) et en prime, toute la classe et ses membres sont entièrement commenté avec XML.

(je l'ai abstenu d'afficher le code ici, car il est vraiment très longue avec tous les commentaires XML.)

Autres conseils

Masquer le Dictionnaire totalement. Il suffit de fournir une méthode get sur la classe DictContainer qui récupère des éléments du dictionnaire.

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public this[int key]
    {
        return myDictionary[key];
    }
}

Eh ... alors ne définit pas la méthode Add ...

Gardez la variable privée et exposer une Getter myDictionary / indexeur afin qu'il ne peut être lu à l'extérieur de cette classe ..

se demande s'il est complètement manquant le point

Il n'y a aucun moyen intégré pour le faire, pensez à utiliser une classe wrapper.

interface IReadOnlyDic<Key, Value>
{
    void Add(Key key, Value value);
}
class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>, IReadOnlyDic<Key, Value>
{
    public new void Add(Key key, Value value)
    {
        //throw an exception or do nothing
    }
    #region IReadOnlyDic<Key,Value> Members

    void IReadOnlyDic<Key, Value>.Add(Key key, Value value)
    {
        base.Add(key, value);
    }

    #endregion
}

pour ajouter des éléments personnalisés;

    IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
    if (dict != null)
        dict.Add(1, 155);

et ceci est une autre façon

class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>
{
    private bool _locked = false;

    public new void Add(Key key, Value value)
    {
        if (!_locked)
        {
            base.Add(key, value);
        }
        else
        {
            throw new ReadOnlyException();
        }
    }
    public void Lock()
    {
        _locked = true;
    }
}

J'ai aimé le de bruno-conde, qui était plus simple, mais une fois que je ne peux pas marquer son commentaire comme la réponse , je vais marquer réponse noldorin comme le fonctionnaire, car il est une réponse similaire et satisfaisante.

Dommage qu'il n'y ait pas un moyen d'empêcher le code de compilation :(. Merci, les gars

Voici une meilleure alternative comme je l'ai décrit à:

http://www.softwarerockstar.com/2010/10/ ..

Pour l'essentiel, il est une solution beaucoup plus simple subclassing ReadOnlyCollection, qui obtient le travail accompli d'une manière plus élégante.

Pour votre information, il est maintenant intégré à 4,5 .net.

http://msdn.microsoft.com /en-us/library/gg712875(v=vs.110).aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top