Diccionario const en C #
-
21-08-2019 - |
Pregunta
Tengo una clase en C # que contiene un diccionario, lo que yo quiero para crear y asegurar que nada como añadido, editado o eliminado de este diccionario, siempre y cuando la clase que lo contiene existe.
de sólo lectura no ayuda, una vez que probé y vi que puedo añadir artículos después. Sólo por ejemplo, he creado un ejemplo:
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);
}
}
Quiero que el método Add para no trabajar. Si es posible, quiero que ni siquiera compilar. ¿Alguna sugerencia?
En realidad, estoy preocupado porque es código que será abierta para una gran cantidad de gente a cambiar. Así que, incluso si oculto el método Add, será posible que alguien "inocentemente" crear un método que añadir una clave, o eliminar otra. Quiero que la gente se ven y sé que no deben cambiar el diccionario en cualquier forma. Al igual que tengo con una variable const.
Solución
No hay nada en el .NET Framework para ayudarle a cabo aquí, pero este post da una muy buena aplicación de un ReadOnlyDictionary
genéricos en C #. Implementa todas las interfaces que se podría esperar que (IDictionary
, ICollection
, IEnumerable
, etc.) y como un bono, toda la clase y sus miembros están completamente comentado con XML.
(he abstenido de publicar el código aquí, porque en realidad es bastante largo con todos los comentarios XML.)
Otros consejos
Ocultar el Diccionario totalmente. Simplemente proporcione un método get en la clase DictContainer que recupera elementos del diccionario.
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 ... entonces no definen el método Add ...
Mantener el myDictionary
variable privada y exponer un captador / controlador paso a paso de forma que sólo se puede leer desde fuera esa clase ..
se pregunta si él está completamente perdiendo el punto
No hay manera integrada para hacer eso, considerar el uso de una clase contenedora.
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
}
para añadir elementos personalizados;
IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
if (dict != null)
dict.Add(1, 155);
y esta es otra manera
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;
}
}
Me gustó el enlace de Bruno-conde , que era uno más sencillo, pero una vez que no puedo marcar su comentario como la respuesta , yo marcaré noldorin respuesta como la oficial, ya que es una respuesta similar y satisfactoria.
Es una pena que no hay una manera de prevenir el código de compilación :(. Gracias, chicos
Aquí hay una alternativa mejor que he descrito en:
http://www.softwarerockstar.com/2010/10/ ..
En esencia se trata de una solución de subclases ReadOnlyCollection mucho más simple, que obtiene el trabajo realizado de una manera más elegante.
Para su información, ya que está construido en a .NET 4.5.
http://msdn.microsoft.com /en-us/library/gg712875(v=vs.110).aspx