Declare um dicionário dentro de uma classe estática

90

Como declarar um objeto de dicionário estático dentro de uma classe estática? eu tentei

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic = new Dictionary<string, string>()
    {
        { "1", "User name or password problem" }     
    };
}

Mas o compilador reclama que " Um campo const de um tipo de referência diferente de string só pode ser inicializado com nulo ".

Graviton
fonte
1
Você não pode usar const com o tipo de Dicionário, apenas com valores escalares. (verifique minha resposta) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

Respostas:

214

Se você quiser declarar o dicionário uma vez e nunca alterá-lo, declare-o como somente leitura:

private static readonly Dictionary<string, string> ErrorCodes
    = new Dictionary<string, string>
{
    { "1", "Error One" },
    { "2", "Error Two" }
};

Se você quiser que os itens do dicionário sejam somente leitura (não apenas a referência, mas também os itens da coleção), você terá que criar uma classe de dicionário somente leitura que implemente IDictionary.

Confira ReadOnlyCollection para referência.

BTW const só pode ser usado ao declarar valores escalares embutidos.

Yona
fonte
Que tal ter uma variável estática privada de nível de classe private static Dictionary <string, string> ErrorCodes e, em seguida, na respectiva função, verificar se (ErrorCodes == null) {preencher o dicionário} para armazenar o valor quando usado em loop?
LifeOfPi
1
Se não quiser que o dicionário seja alterado, você pode agrupá-lo em um ReadOnlyDictionary. Uma opção mais eficiente (mas menos segura) é atribuí-lo a um IReadOnlyDictionarytipo.
Ramon de Klein
8

A sintaxe correta (conforme testado no VS 2008 SP1), é esta:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Graviton
fonte
Mas isso não impede que uma classe consumidora modifique o conteúdo.
Revisa em
4

Pergunta antiga, mas achei isso útil. Acontece que também existe uma classe especializada para um Dicionário usando uma string para a chave e o valor:

private static readonly StringDictionary SegmentSyntaxErrorCodes = new StringDictionary
{
    { "1", "Unrecognized segment ID" },
    { "2", "Unexpected segment" }
};

Edit: De acordo com o comentário de Chris abaixo, usar Dictionary<string, string>over StringDictionaryé geralmente preferido, mas dependerá da sua situação. Se você estiver lidando com uma base de código mais antiga, pode estar limitado a StringDictionary. Além disso, observe que a seguinte linha:

myDict["foo"]

retornará null se myDictfor a StringDictionary, mas uma exceção será lançada no caso de Dictionary<string, string>. Veja o post do SO que ele mencionou para mais informações, que é a fonte desta edição.

areyling
fonte
Essa é exatamente a pergunta à qual vinculei.
Chris Morgan
1
Ha uau, nem percebi isso - apenas aconteceu de encontrar o mesmo. Não consegui editar o comentário, então apenas editei a postagem para resumir em um único lugar. Obrigado!
areyling
1

O problema com seu exemplo inicial foi principalmente devido ao uso de, em constvez de static; você não pode criar uma referência const não nula em C #.

Eu acredito que isso também teria funcionado:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic
        = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
}

Além disso, como Y Low aponta, adicionar também readonlyé uma boa ideia, e nenhum dos modificadores discutidos aqui impedirá que o próprio dicionário seja modificado.

Charlie
fonte
1

Crie um construtor estático para adicionar valores no Dicionário

enum Commands
{
    StudentDetail
}
public static class Quires
{
    public static Dictionary<Commands, String> quire
        = new Dictionary<Commands, String>();
    static Quires()
    {
        quire.add(Commands.StudentDetail,@"SELECT * FROM student_b");
    }
}
Sujith Radhakrishnan
fonte
1
quire ou query?
Ash
0

Faça do dicionário um estático, e nunca adicione a ele fora do ctor do seu objeto estático. Essa parece ser uma solução mais simples do que brincar com as regras estáticas / const em C #.

Jeff Hubbard
fonte
-1

Você pode usar o construtor static / class para inicializar seu dicionário:

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic;
    public static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Andy
fonte
1
Você quis dizer tornar o dicionário estático? Você não pode ter const. Como diz a mensagem de erro, apenas tipos de valor, strings ou nulos podem ser const
Orion Edwards
-2
public static class ErrorCode
{
    public const IDictionary<string , string > m_ErrorCodeDic;

    public static ErrorCode()
    {
      m_ErrorCodeDic = new Dictionary<string, string>()
             { {"1","User name or password problem"} };             
    }
}

Provavelmente inicialize no construtor.

Craig
fonte