const dicionário em c #
-
21-08-2019 - |
Pergunta
Eu tenho uma classe em C # que contém um dicionário, o que eu quero criar e assegurar que nada como adicionado, editado ou removido deste dicionário, enquanto a classe que contém ela existe.
readonly realmente não ajuda, uma vez que eu testei e vi que eu posso adicionar itens depois. Apenas por exemplo, eu criei um exemplo:
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);
}
}
Eu quero o método Add não ao trabalho. Se possível, eu quero que ele nem sequer compilar. Alguma sugestão?
Na verdade, estou preocupado porque é código que será aberto para um monte de pessoas para a mudança. Assim, mesmo se eu esconder o método Add, será possível para alguém "inocentemente" criar um método que adicionar uma chave, ou remover outro. Quero que as pessoas a olhar e sei que eles não devem alterar o dicionário em todas as maneiras. Assim como eu tenho com uma variável const.
Solução
Não há nada no .NET Framework para ajudá-lo aqui, mas este post dá uma boa implementação muito de um ReadOnlyDictionary
genéricos em C #. Ele implementa todas as interfaces que você pode esperar que ele (IDictionary
, ICollection
, IEnumerable
, etc.) e como um bônus, toda a classe e seus membros são totalmente comentado com XML.
(eu absteve-se de publicar o código aqui, porque é realmente bastante longo com todos os comentários XML.)
Outras dicas
Ocultar o dicionário totalmente. Basta fornecer um método get na classe DictContainer que recupera itens do dicionário.
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 ... então não definem o método Add ...
Mantenha a variável myDictionary
privado e expor um Getter / indexador de modo que só pode ser lido de fora dessa classe ..
pergunta se ele está perdendo completamente o ponto
Não há nenhuma built-in maneira de fazer isso, considere o uso um envoltório classe.
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 adicionar itens personalizados;
IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
if (dict != null)
dict.Add(1, 155);
e esta é outra maneira
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;
}
}
Eu gostei da ligação from bruno-conde , que era uma mais simples, mas uma vez eu não posso marcar seu comentário como a resposta , eu vou marcar noldorin resposta como o oficial, pois é uma resposta semelhante e satisfatório.
Pena que não há uma maneira de impedir que o código de compilação :(. Obrigado, pessoal
Aqui está uma alternativa melhor, como eu descrevi em:
http://www.softwarerockstar.com/2010/10/ ..
Essencialmente é uma solução muito mais simples subclasse ReadOnlyCollection, que recebe o trabalho feito de uma forma mais elegante.
FYI, agora é built-in para .NET 4.5.
http://msdn.microsoft.com /en-us/library/gg712875(v=vs.110).aspx