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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top