Domanda

Ho una classe in C # che contiene un Dizionario, che voglio creare e garantire che niente, come aggiunto, modificato o rimosso da questo dizionario fintanto che la classe che lo contiene esiste.

in sola lettura non aiuta, una volta che ho provato e ho visto che posso aggiungere articoli dopo. Solo per esempio, ho creato un esempio:

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

}

Voglio che il metodo Add non lavorare. Se possibile, lo voglio, non compilare nemmeno. Qualche suggerimento?

In realtà, io sono preoccupato perché è il codice che sarà aperto per un sacco di persone a cambiare. Quindi, anche se mi nascondo il metodo Add, sarà possibile per qualcuno "innocentemente" creare un metodo che aggiungere una chiave, o rimuovere un'altra. Voglio che la gente a guardare e so che non dovrebbe cambiare il dizionario in alcun modo. Proprio come ho con una variabile const.

È stato utile?

Soluzione

Non c'è niente in .NET Framework per aiutarti qui, ma questo post dà una buona implementazione di una ReadOnlyDictionary generica in C #. Esso implementa tutte le interfacce si potrebbe aspettare a (IDictionary, ICollection, IEnumerable, etc.) e come bonus, l'intera classe ed i suoi membri sono completamente commentato con XML.

(ho evitato di inviare il codice qui, perché è davvero molto lungo con tutti i commenti XML.)

Altri suggerimenti

Nascondere il dizionario del tutto. Basta fornire un metodo get sulla classe DictContainer che recupera gli elementi dal dizionario.

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 ... allora non definire il metodo Add ...

Tenere il myDictionary variabile privata ed esporre un getter / indicizzatore in modo che possa essere letto solo dall'esterno quella classe ..

si chiede se lui è completamente manca il punto

Non c'è alcun modo incorporato per fare questo, è consigliabile utilizzare un 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
}

per aggiungere elementi personalizzati;

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

e questo è un altro modo

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

Mi è piaciuto il link bruno-conde, che è stato uno più semplice, ma una volta non riesco a segnare il suo commento come la risposta , io lo segnaliamo Noldorin risposta come il funzionario, perché è una risposta simile e soddisfacente.

Peccato che non ci sia un modo per evitare che il codice da compilare :(. Grazie, ragazzi

Ecco un'alternativa migliore come ho descritto in:

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

In sostanza si tratta di una soluzione di ReadOnlyCollection sottoclasse molto più semplice, che ottiene il lavoro fatto in un modo più elegante.

Cordiali saluti, adesso è built-in a .NET 4.5.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top