'string const' vs. 'string somente leitura estática' em C #


Respostas:


171

Quando você usa uma conststring, o compilador incorpora o valor da string em tempo de compilação .
Portanto, se você usar um constvalor em uma montagem diferente, atualizar a montagem original e alterar o valor, a outra montagem não verá a alteração até que você a recompile .

Uma static readonlystring é um campo normal que é pesquisado em tempo de execução. Portanto, se o valor do campo for alterado em um assembly diferente, as alterações serão vistas assim que o assembly for carregado, sem recompilar.

Isso também significa que uma static readonlystring pode usar membros não constantes, como Environment.UserNameou DateTime.Now.ToString(). Uma conststring só pode ser inicializada usando outras constantes ou literais.
Além disso, uma static readonlystring pode ser definida em um construtor estático; uma conststring só pode ser inicializada inline.

Observe que a static stringpode ser modificado; você deve usar em seu static readonlylugar.


25
+1, E a conclusão óbvia, de um ponto de vista prático e semântico: constsó deve ser usado para constantes - constantes sendo valores que nunca , nunca , nunca mudam.
LukeH

3
@LukeH nunca, nunca, nunca é um pouco forte. Não consigo pensar em nada de ruim que aconteceria se alguém declarasse uma string privada como const e a alterasse entre dois eventos de recompilação.
Brenda Bell

5
@Brenda: Admito que uso private constpara valores que não são, estritamente falando, constantes; basicamente é mau uso constpara fins de micro-otimização. Vou manter minha declaração "nunca, nunca, nunca" , mesmo que isso me torne um hipócrita. ;)
LucasH

E quanto ao desempenho no caso de cordas em particular? Cada uso de const produzirá uma nova cópia de uma string na memória?
Andrii

@Andrii não, strings constantes são criadas uma vez. Cada uso terá a mesma referência na memória.
Migg

43

Aqui está uma boa análise dos prós e contras :

Portanto, parece que as constantes devem ser usadas quando é muito improvável que o valor mude, ou se nenhum aplicativo / biblioteca externo estiver usando a constante. Os campos estáticos somente leitura devem ser usados ​​quando o cálculo do tempo de execução for necessário ou se consumidores externos forem um fator.


19
Ponto muito interessante do artigo - "Em um alto nível, as constantes são obviamente tratadas em tempo de compilação, enquanto os campos estáticos somente leitura são definidos no momento em que são avaliados em tempo de execução. O fato de que os valores constantes são substituídos pelo compilador significa que qualquer biblioteca / montagem que faça referência ao valor constante precisará ser recompilado se o valor da constante mudar. Bibliotecas que fazem referência a um campo somente leitura estático farão referência ao campo e não ao valor, portanto, irão pegar qualquer mudança no campo sem a necessidade para recompilação "
s_hewitt

1
Sim, eu li isso também e tive um momento huh. Eu definitivamente não sabia disso.
spinon

Aqui é o Google em cache versão: webcache.googleusercontent.com/...
spinon

2
O link de referência não está mais disponível.
Salomon Zhang,

Este é um excelente elogio à resposta assinalada como solução. Definir o uso é muito útil. +1 de mim.
Bonez024

11

const

public const string MyStr;

é uma constante de tempo de compilação (você pode usá-la como o parâmetro padrão para um parâmetro de método, por exemplo), e não será ofuscada se você usar essa tecnologia

static readonly

public static readonly string MyStr;

é constante de tempo de execução . Isso significa que ele é avaliado quando o aplicativo é iniciado e não antes. É por isso que ele não pode ser usado como o parâmetro padrão para um método (erro de compilação), por exemplo. O valor armazenado nele pode ser ofuscado.


6

OQ perguntado sobre static stringvs const. Ambos têm casos de uso diferentes (embora ambos sejam tratados como estáticos).

Use const apenas para valores verdadeiramente constantes (por exemplo, velocidade da luz - mas mesmo isso varia dependendo do meio). A razão para esta orientação estrita é que o valor const é substituído nos usos de const em assemblies que o referenciam, o que significa que você pode ter problemas de versão caso const mude em seu lugar de definição (ou seja, não deveria ser uma constante depois de tudo). Observe que isso afeta até os private constcampos porque você pode ter base e subclasse em diferentes assemblies e os campos privados são herdados .

Os campos estáticos estão vinculados ao tipo em que são declarados. Eles são usados ​​para representar valores que precisam ser os mesmos para todas as instâncias de um determinado tipo. Esses campos podem ser gravados quantas vezes você quiser (a menos que especificado somente leitura).

Se você quis dizer static readonlyvs const, eu recomendaria static readonlypara quase todos os casos porque é mais à prova de futuro.


De quem é esse "OQ" de quem você fala?
Peter Mortensen

“Pergunta original”
Ben Aston

0

Você pode alterar o valor de a static readonly stringapenas no staticconstrutor da classe ou em um inicializador de variável, enquanto você não pode alterar o valor de uma conststring em qualquer lugar.


2
Não vejo como isso acrescenta algo além do que as respostas existentes já dizem.
Processo de Fundo Monica
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.