const dizionario in C #
-
21-08-2019 - |
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.
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