@donstack, na verdade, de acordo com a referência C # , um campo somente leitura pode ser atribuído e reatribuído várias vezes na declaração e no construtor.
Marques
Respostas:
1289
Além da aparente diferença de
ter que declarar o valor no momento de uma definição para valores de constVS readonlypode ser calculado dinamicamente, mas precisa ser atribuído antes que o construtor saia .. depois disso, ele é congelado.
'const's são implicitamente static. Você usa uma ClassName.ConstantNamenotação para acessá-los.
Há uma diferença sutil. Considere uma classe definida em AssemblyA.
AssemblyBreferencia AssemblyAe usa esses valores no código. Quando isso é compilado,
no caso do constvalor, é como uma substituição de localização, o valor 2 é 'incorporado à AssemblyB' IL. Isso significa que, se amanhã eu atualizar I_CONST_VALUEpara 20 no futuro. AssemblyBainda teria 2 até eu recompilar .
no caso do readonlyvalor, é como um reflocal de memória. O valor não está inserido AssemblyBna IL. Isso significa que, se o local da memória for atualizado, AssemblyBobtém o novo valor sem recompilação. Portanto, se I_RO_VALUEfor atualizado para 30, você precisará criar apenas AssemblyA. Todos os clientes não precisam ser recompilados.
Portanto, se você estiver confiante de que o valor da constante não mudará, use a const.
publicconstint CM_IN_A_METER =100;
Mas se você tem uma constante que pode mudar (por exemplo, precisão de escrita) .. ou em caso de dúvida, use a readonly.
publicreadonlyfloat PI =3.14;
Atualização: Aku precisa fazer uma menção porque ele apontou isso primeiro. Também preciso conectar onde aprendi isso. C # eficaz - Bill Wagner
O staticponto parece ser o ponto mais importante e útil -consts are implicitly static
LCJ
28
A parte sobre valores de referência é a mais importante. Os valores Const podem ser otimizados.
precisa saber é o seguinte
22
readonlyvariáveis podem ser alteradas fora do construtor (reflexão). É apenas o compilador que tenta impedir você de modificar o var fora do construtor.
Bitterblue
12
As readonlyvariáveis @ mini-me não podem ser alteradas após a conclusão do construtor, mesmo através da reflexão. O tempo de execução não impõe isso. O tempo de execução também acontece para não impor que você não mudar string.Emptypara "Hello, world!", mas eu ainda não diria que isso faz string.Emptymodificáveis, ou que o código não deve assumir que string.Emptyserá sempre uma cadeia de comprimento zero.
Há uma pegadinha com consts! Se você referenciar uma constante de outra montagem, seu valor será compilado diretamente na montagem de chamada. Dessa forma, quando você atualiza a constante na montagem referenciada, ela não muda na montagem de chamada!
Na descompilação (Reflector, ILSpy, ..), uma constante NUNCA NUNCA é referenciada por ninguém, não importa a mesma montagem ou outra montagem, portanto, você não pode analisar o uso de uma constante no código compilado.
precisa saber é
159
Constantes
Constantes são estáticas por padrão
Eles devem ter um valor no momento da compilação (você pode ter, por exemplo, 3,14 * 2, mas não pode chamar métodos)
Pode ser declarado dentro de funções
São copiados para cada montagem que os utiliza (toda montagem obtém uma cópia local dos valores)
Pode ser usado em atributos
Campos de instância somente leitura
Deve ter um valor definido, no momento em que o construtor sai
São avaliados quando a instância é criada
Campos estáticos somente leitura
São avaliados quando a execução do código atinge a referência de classe (quando uma nova instância é criada ou um método estático é executado)
Deve ter um valor avaliado no momento em que o construtor estático é concluído
Não é recomendável colocar ThreadStaticAttribute neles (os construtores estáticos serão executados em apenas um thread e definirão o valor para seu thread; todos os outros threads terão esse valor não inicializado)
Apenas para adicionar, o ReadOnly somente para tipos de referência torna a referência somente leitura, não os valores. Por exemplo:
publicclassConst_V_Readonly{publicconstint I_CONST_VALUE =2;publicreadonlychar[] I_RO_VALUE =newChar[]{'a','b','c'};publicUpdateReadonly(){
I_RO_VALUE[0]='V';//perfectly legal and will update the value
I_RO_VALUE =newchar[]{'V'};//will cause compiler error}}
Existe algum outro tipo de referência stringque você possa usar como constante?
precisa saber é
Você pode ter constcom tipos de referência diferentes de sequência, mas a constante pode ter apenas o valor null.
Mike Rosoft
40
Isso explica isso . Resumo: const deve ser inicializado no momento da declaração, somente leitura pode ser inicializado no construtor (e, portanto, ter um valor diferente, dependendo do construtor usado).
EDIT: Veja a pegadinha de Gishu acima para a diferença sutil
Há uma pequena pegadinha com somente leitura. Um campo somente leitura pode ser definido várias vezes no (s) construtor (es). Mesmo que o valor seja definido em dois construtores encadeados diferentes, ele ainda é permitido.
publicclassSample{privatereadonlystring ro;publicSample(){
ro ="set";}publicSample(stringvalue):this(){
ro =value;// this works even though it was set in the no-arg ctor}}
Um membro constante é definido no tempo de compilação e não pode ser alterado no tempo de execução. As constantes são declaradas como um campo, usando a constpalavra - chave e devem ser inicializadas conforme são declaradas.
Um readonlymembro é como uma constante, pois representa um valor imutável. A diferença é que um readonlymembro pode ser inicializado em tempo de execução, em um construtor, além de poder ser inicializado conforme declarado.
Eles não podem ser estáticos , eles são estáticos. Você deve deixar claro se você quis dizer que não se pode declararstatic const int i = 0;
Nawfal
Você pode explicar por que as constdeclarações não podem ser feitas dentro de métodos?
Minh Tran
21
Uma const é uma constante em tempo de compilação, enquanto que somente leitura permite que um valor seja calculado em tempo de execução e definido no construtor ou inicializador de campo. Portanto, uma 'const' é sempre constante, mas 'readonly' é somente leitura quando é atribuída.
Eric Lippert, da equipe C #, tem mais informações sobre diferentes tipos de imutabilidade
Aqui está outro link demonstra como const não é uma versão segura ou relevante para tipos de referência.
Resumo :
O valor da sua propriedade const é definido no tempo de compilação e não pode ser alterado no tempo de execução
Const não pode ser marcado como estático - a palavra-chave indica que eles são estáticos, diferentemente dos campos somente leitura que podem.
Const não pode ser nada, exceto tipos de valor (primitivo)
A palavra-chave readonly marca o campo como imutável. No entanto, a propriedade pode ser alterada dentro do construtor da classe
A palavra-chave somente leitura também pode ser combinada com estática para fazê-la agir da mesma maneira que uma const (pelo menos na superfície). Há uma diferença marcante quando você olha para o IL entre os dois
os campos const são marcados como "literais" em IL enquanto readonly é "initonly"
Eu acredito que um constvalor é o mesmo para todos os objetos (e deve ser inicializado com uma expressão literal), enquanto readonlypode ser diferente para cada instanciação ...
Um dos membros da equipe em nosso escritório forneceu as seguintes orientações sobre quando usar const, static e readonly:
Use const quando tiver uma variável de um tipo que você possa saber em tempo de execução (string literal, int, double, enums, ...) que deseja que todas as instâncias ou consumidores de uma classe tenham acesso a onde o valor não deve mudar.
Use estática quando você tiver dados que deseja que todas as instâncias ou consumidores de uma classe tenham acesso a onde o valor pode mudar.
Use estática somente leitura quando você tiver uma variável de um tipo que não possa saber em tempo de execução (objetos) que deseja que todas as instâncias ou consumidores de uma classe tenham acesso a onde o valor não deve ser alterado.
Use somente leitura quando tiver uma variável no nível da instância que você saberá no momento da criação do objeto que não deve mudar.
Uma nota final: um campo const é estático, mas o inverso não é verdadeiro.
Eu acho que você quer dizer "conversar". O inverso seria "um campo não-const não é estático". O que pode ou não ser verdade. O contrário, "um campo estático é (sempre) const" não é verdadeiro.
Michael Blackburn
5
Ambos são constantes, mas uma const está disponível também em tempo de compilação. Isso significa que um aspecto da diferença é que você pode usar variáveis const como entrada para atribuir construtores, mas não variáveis somente leitura.
Exemplo:
publicstaticclassText{publicconststringConstDescription="This can be used.";publicreadonlystaticstringReadonlyDescription="Cannot be used.";}publicclassFoo{[Description(Text.ConstDescription)]publicintBarThatBuilds{{get;set;}}[Description(Text.ReadOnlyDescription)]publicintBarThatDoesNotBuild{{get;set;}}}
constante em tempo de compilação : constante absoluta , o valor é definido durante a declaração, está no próprio código IL
readonly
constante de tempo de execução : pode ser definida no construtor / init via arquivo de configuração App.config, mas, uma vez inicializada, não pode ser alterada
As variáveis marcadas como const são pouco mais do que macros #define fortemente tipadas; no tempo de compilação, as referências às variáveis const são substituídas por valores literais embutidos. Como conseqüência, apenas certos tipos de valores primitivos internos podem ser usados dessa maneira. As variáveis marcadas como somente leitura podem ser definidas, em um construtor, no tempo de execução e sua somente leitura é imposta também durante o tempo de execução. Existe um custo menor de desempenho associado a isso, mas significa que você pode usar somente leitura com qualquer tipo (mesmo tipos de referência).
Além disso, variáveis const são inerentemente estáticas, enquanto variáveis readonly podem ser específicas da instância, se desejado.
Adicionado que consts são macros #define fortemente tipadas . Caso contrário, podemos assustar todas as pessoas C ou C ++. :-)
Jason Baker
4
CONST
A palavra-chave const pode ser aplicada a campos ou variáveis locais
Devemos atribuir um campo const no momento da declaração
Nenhuma memória alocada Porque o valor const é incorporado no próprio código IL após a compilação. É como encontrar todas as ocorrências da variável const e substituir por seu valor. Portanto, o código IL após a compilação terá valores codificados no lugar das variáveis const
Const em C # são, por padrão, estáticos.
O valor é constante para todos os objetos
Há um problema de versão da dll - Isso significa que sempre que alteramos uma variável ou propriedade pública const (na verdade, não é para ser alterada teoricamente), qualquer outra dll ou assembly que use essa variável deve ser reconstruída
Somente tipos internos de C # podem ser declarados como constantes
O campo Const não pode ser passado como parâmetro ref ou out
Somente leitura
a palavra-chave readonly se aplica apenas a campos e não a variáveis locais
Podemos atribuir campo somente leitura no momento da declaração ou no construtor, não em nenhum outro método.
memória dinâmica alocada para campos somente leitura e podemos obter o valor em tempo de execução.
O Readonly pertence ao objeto criado, portanto, acessado através apenas da instância da classe. Para torná-lo membro da classe, precisamos adicionar uma palavra-chave estática antes da leitura.
O valor pode ser diferente dependendo do construtor usado (pois pertence ao objeto da classe)
Se você declarar tipos não primitivos (tipo de referência) como somente leitura, a referência será imutável, e não o objeto que ele contém.
Como o valor é obtido no tempo de execução, não há problema de versão da dll com campos / propriedades somente leitura.
Podemos passar o campo somente leitura como parâmetros ref ou out no contexto do construtor.
Como const realmente funciona apenas com tipos de dados básicos, se você deseja trabalhar com uma classe, pode se sentir "forçado" a usar o ReadOnly. No entanto, cuidado com a armadilha! ReadOnly significa que você não pode substituir o objeto por outro (você não pode fazer com que ele se refira a outro objeto). Mas qualquer processo que tenha uma referência ao objeto é livre para modificar os valores dentro do objeto!
Portanto, não se confunda ao pensar que o ReadOnly implica que um usuário não pode mudar as coisas. Não há sintaxe simples em C # para impedir que uma instanciação de uma classe altere seus valores internos (tanto quanto eu sei).
Sim, isso é mais um tema geral. Se você tiver uma propriedade get only expondo uma lista de matrizes, ainda poderá modificar a lista de matrizes. Você não pode definir uma lista de matrizes diferente para essa propriedade, mas não pode impedir o usuário de alterar a lista de matrizes.
Gishu
3
A constdeve ser codificado , onde readonlypode ser definido no construtor da classe.
Há uma diferença notável entre os campos const e somente leitura em C # .Net
const é, por padrão, estático e precisa ser inicializado com valor constante, que não pode ser modificado posteriormente. Mudança de valor também não é permitida em construtores. Não pode ser usado com todos os tipos de dados. Por ex DateTime. Não pode ser usado com o tipo de dados DateTime.
readonly pode ser declarado como estático, mas não necessário. Não há necessidade de inicializar no momento da declaração. Seu valor pode ser atribuído ou alterado usando o construtor. Portanto, oferece vantagem quando usado como membro da classe de instância. Duas instâncias diferentes podem ter um valor diferente do campo somente leitura. Por ex -
class A
{publicreadonlyintId;public A(int i){Id= i;}}
Em seguida, o campo somente leitura pode ser inicializado com valores específicos instantâneos, da seguinte maneira:
A objOne =new A(5);
A objTwo =new A(10);
Aqui, a instância objOne terá o valor do campo somente leitura como 5 e objTwo tem 10. O que não é possível usando const.
Uma constante será compilada no consumidor como um valor literal, enquanto a sequência estática servirá como uma referência ao valor definido.
Como exercício, tente criar uma biblioteca externa e consumi-la em um aplicativo de console, altere os valores na biblioteca e recompile-a (sem recompilar o programa do consumidor), solte a DLL no diretório e execute o EXE manualmente, você deve encontrar que a cadeia constante não muda.
@ Andrew Hare - sim, acabei de verificar. Estou muito surpreso, isso é uma verdadeira pegadinha, estou realmente muito surpreso com isso, espantado que seja o caso ...!
ljs 8/09/09
Objeto, no entanto, o uso da palavra ponteiro aqui. Não é um ponteiro, é uma referência, e não é uma diferença em C #, como você pode manipular ponteiros não gerenciados no modo inseguro por isso é importante fazer a distinção entre os dois.
ljs 8/09/09
2
Constante
Precisamos fornecer o valor para o campo const quando ele é definido. O compilador salva o valor da constante nos metadados do assembly. Isso significa que uma constante pode ser definida apenas para o tipo primitivo, como booleano, char, byte e assim por diante. As constantes são sempre consideradas membros estáticos, não membros da instância.
Somente leitura
Os campos somente leitura podem ser resolvidos em tempo de execução. Isso significa que podemos definir um valor para um valor usando o construtor para o tipo em que o campo é declarado. A verificação é feita pelo compilador de que os campos somente leitura não são gravados por nenhum método que não seja o construtor.
Principalmente; você pode atribuir um valor a um campo estático somente leitura a um valor não constante em tempo de execução, enquanto uma const deve ser atribuída a um valor constante.
Const e somente leitura são semelhantes, mas não são exatamente iguais. Um campo const é uma constante em tempo de compilação, o que significa que esse valor pode ser calculado em tempo de compilação. Um campo somente leitura permite cenários adicionais em que algum código deve ser executado durante a construção do tipo. Após a construção, um campo somente leitura não pode ser alterado.
Por exemplo, membros const podem ser usados para definir membros como:
já que valores como 3,14 e 0 são constantes em tempo de compilação. No entanto, considere o caso em que você define um tipo e deseja fornecer algumas instâncias pré-fabricadas. Por exemplo, você pode definir uma classe Color e fornecer "constantes" para cores comuns, como preto, branco etc. Não é possível fazer isso com membros const, pois o lado direito não é uma constante em tempo de compilação. Pode-se fazer isso com membros estáticos regulares:
publicclassColor{publicstaticColorBlack=newColor(0,0,0);publicstaticColorWhite=newColor(255,255,255);publicstaticColorRed=newColor(255,0,0);publicstaticColorGreen=newColor(0,255,0);publicstaticColorBlue=newColor(0,0,255);privatebyte red, green, blue;publicColor(byte r,byte g,byte b){
red = r;
green = g;
blue = b;}}
mas não há nada que impeça um cliente da Color de trocá-lo, talvez trocando os valores de preto e branco. Escusado será dizer que isso causaria consternação para outros clientes da classe Color. O recurso "somente leitura" aborda esse cenário. Simplesmente introduzindo a palavra-chave readonly nas declarações, preservamos a inicialização flexível e impedimos que o código do cliente mexa.
publicclassColor{publicstaticreadonlyColorBlack=newColor(0,0,0);publicstaticreadonlyColorWhite=newColor(255,255,255);publicstaticreadonlyColorRed=newColor(255,0,0);publicstaticreadonlyColorGreen=newColor(0,255,0);publicstaticreadonlyColorBlue=newColor(0,0,255);privatebyte red, green, blue;publicColor(byte r,byte g,byte b){
red = r;
green = g;
blue = b;}}
É interessante notar que os membros const são sempre estáticos, enquanto um membro somente leitura pode ser estático ou não, assim como um campo regular.
É possível usar uma única palavra-chave para esses dois propósitos, mas isso leva a problemas de versão ou de desempenho. Suponhamos por um momento que usamos uma única palavra-chave para isso (const) e um desenvolvedor escreveu:
publicclass A
{publicstaticconst C =0;}
e um desenvolvedor diferente escreveu um código que contava com A:
publicclass B
{staticvoidMain(){Console.WriteLine(A.C);}}
Agora, o código gerado pode confiar no fato de que o AC é uma constante em tempo de compilação? Ou seja, o uso de AC pode simplesmente ser substituído pelo valor 0? Se você disser "sim" a isso, isso significa que o desenvolvedor de A não pode mudar a maneira como o CA é inicializado - isso amarra as mãos do desenvolvedor de A sem permissão. Se você disser "não" a esta pergunta, uma otimização importante será perdida. Talvez o autor de A tenha certeza de que AC sempre será zero. O uso de const e readonly permite que o desenvolvedor de A especifique a intenção. Isso contribui para um melhor comportamento de versão e também um melhor desempenho.
ReadOnly: o valor será inicializado apenas uma vez a partir do construtor da classe.
const: pode ser inicializado em qualquer função, mas apenas uma vez
A diferença é que o valor de um campo estático somente leitura é definido em tempo de execução, para que ele possa ter um valor diferente para diferentes execuções do programa. No entanto, o valor de um campo const é definido como uma constante de tempo de compilação.
Lembre-se: Para tipos de referência, nos dois casos (estático e instância), o modificador somente leitura impede que você atribua uma nova referência ao campo. Especificamente, não torna imutável o objeto apontado pela referência.
Variáveis constantes são declaradas e inicializadas em tempo de compilação. O valor não pode ser alterado após as alas. As variáveis somente leitura serão inicializadas apenas no construtor Static da classe. Somente leitura é usado apenas quando queremos atribuir o valor em tempo de execução.
Sua definição de 'Somente leitura' de que ele pode mudar é falha. Eu acho que por 'mudança' você quis dizer 'definir', como 'pode ser definido em tempo de execução'.
Ahmed
0
Uma coisa a acrescentar ao que as pessoas disseram acima. Se você tiver uma montagem contendo um valor somente leitura (por exemplo, somente MaxFooCount = 4;), poderá alterar o valor que os assemblies chamadores veem enviando uma nova versão dessa montagem com um valor diferente (por exemplo, somente MaxFooCount = 5;)
Mas com uma const, seria dobrada no código do chamador quando o compilador fosse compilado.
Se você atingiu esse nível de proficiência em C #, está pronto para o livro de Bill Wagner, C # efetivo: 50 maneiras específicas de melhorar seu C # O que responde a essa pergunta em detalhes (e 49 outras coisas).
Respostas:
Além da aparente diferença de
const
VSreadonly
pode ser calculado dinamicamente, mas precisa ser atribuído antes que o construtor saia .. depois disso, ele é congelado.static
. Você usa umaClassName.ConstantName
notação para acessá-los.Há uma diferença sutil. Considere uma classe definida em
AssemblyA
.AssemblyB
referenciaAssemblyA
e usa esses valores no código. Quando isso é compilado,const
valor, é como uma substituição de localização, o valor 2 é 'incorporado àAssemblyB
' IL. Isso significa que, se amanhã eu atualizarI_CONST_VALUE
para 20 no futuro.AssemblyB
ainda teria 2 até eu recompilar .readonly
valor, é como umref
local de memória. O valor não está inseridoAssemblyB
na IL. Isso significa que, se o local da memória for atualizado,AssemblyB
obtém o novo valor sem recompilação. Portanto, seI_RO_VALUE
for atualizado para 30, você precisará criar apenasAssemblyA
. Todos os clientes não precisam ser recompilados.Portanto, se você estiver confiante de que o valor da constante não mudará, use a
const
.Mas se você tem uma constante que pode mudar (por exemplo, precisão de escrita) .. ou em caso de dúvida, use a
readonly
.Atualização: Aku precisa fazer uma menção porque ele apontou isso primeiro. Também preciso conectar onde aprendi isso. C # eficaz - Bill Wagner
fonte
static
ponto parece ser o ponto mais importante e útil -consts are implicitly static
readonly
variáveis podem ser alteradas fora do construtor (reflexão). É apenas o compilador que tenta impedir você de modificar o var fora do construtor.readonly
variáveis @ mini-me não podem ser alteradas após a conclusão do construtor, mesmo através da reflexão. O tempo de execução não impõe isso. O tempo de execução também acontece para não impor que você não mudarstring.Empty
para"Hello, world!"
, mas eu ainda não diria que isso fazstring.Empty
modificáveis, ou que o código não deve assumir questring.Empty
será sempre uma cadeia de comprimento zero.Há uma pegadinha com consts! Se você referenciar uma constante de outra montagem, seu valor será compilado diretamente na montagem de chamada. Dessa forma, quando você atualiza a constante na montagem referenciada, ela não muda na montagem de chamada!
fonte
Constantes
Campos de instância somente leitura
Campos estáticos somente leitura
fonte
Apenas para adicionar, o ReadOnly somente para tipos de referência torna a referência somente leitura, não os valores. Por exemplo:
fonte
string
que você possa usar como constante?const
com tipos de referência diferentes de sequência, mas a constante pode ter apenas o valornull
.Isso explica isso . Resumo: const deve ser inicializado no momento da declaração, somente leitura pode ser inicializado no construtor (e, portanto, ter um valor diferente, dependendo do construtor usado).
EDIT: Veja a pegadinha de Gishu acima para a diferença sutil
fonte
const
: Não pode ser alterado em lugar nenhum.readonly
: Esse valor pode ser alterado apenas no construtor. Não pode ser alterado em funções normais.fonte
Há uma pequena pegadinha com somente leitura. Um campo somente leitura pode ser definido várias vezes no (s) construtor (es). Mesmo que o valor seja definido em dois construtores encadeados diferentes, ele ainda é permitido.
fonte
Um membro constante é definido no tempo de compilação e não pode ser alterado no tempo de execução. As constantes são declaradas como um campo, usando a
const
palavra - chave e devem ser inicializadas conforme são declaradas.Um
readonly
membro é como uma constante, pois representa um valor imutável. A diferença é que umreadonly
membro pode ser inicializado em tempo de execução, em um construtor, além de poder ser inicializado conforme declarado.const
static
(eles são implicitamente estáticos)somente leitura
fonte
static const int i = 0;
const
declarações não podem ser feitas dentro de métodos?Uma const é uma constante em tempo de compilação, enquanto que somente leitura permite que um valor seja calculado em tempo de execução e definido no construtor ou inicializador de campo. Portanto, uma 'const' é sempre constante, mas 'readonly' é somente leitura quando é atribuída.
Eric Lippert, da equipe C #, tem mais informações sobre diferentes tipos de imutabilidade
fonte
Aqui está outro link demonstra como const não é uma versão segura ou relevante para tipos de referência.
Resumo :
fonte
Somente leitura : o valor pode ser alterado através do Ctor em tempo de execução. Mas não através da função membro
Constante : Por padrão estático. O valor não pode ser alterado de qualquer lugar (Ctor, Função, tempo de execução etc, não-onde)
fonte
Ainda outro problema: valores somente leitura podem ser alterados por código "desonesto" via reflexão.
Posso alterar um campo herdado privado somente de leitura em C # usando reflexão?
fonte
Eu acredito que um
const
valor é o mesmo para todos os objetos (e deve ser inicializado com uma expressão literal), enquantoreadonly
pode ser diferente para cada instanciação ...fonte
Um dos membros da equipe em nosso escritório forneceu as seguintes orientações sobre quando usar const, static e readonly:
Uma nota final: um campo const é estático, mas o inverso não é verdadeiro.
fonte
Ambos são constantes, mas uma const está disponível também em tempo de compilação. Isso significa que um aspecto da diferença é que você pode usar variáveis const como entrada para atribuir construtores, mas não variáveis somente leitura.
Exemplo:
fonte
quando usar
const
oureadonly
const
readonly
App.config
, mas, uma vez inicializada, não pode ser alteradafonte
As variáveis marcadas como const são pouco mais do que macros #define fortemente tipadas; no tempo de compilação, as referências às variáveis const são substituídas por valores literais embutidos. Como conseqüência, apenas certos tipos de valores primitivos internos podem ser usados dessa maneira. As variáveis marcadas como somente leitura podem ser definidas, em um construtor, no tempo de execução e sua somente leitura é imposta também durante o tempo de execução. Existe um custo menor de desempenho associado a isso, mas significa que você pode usar somente leitura com qualquer tipo (mesmo tipos de referência).
Além disso, variáveis const são inerentemente estáticas, enquanto variáveis readonly podem ser específicas da instância, se desejado.
fonte
CONST
Somente leitura
fonte
Outra pegadinha .
Como const realmente funciona apenas com tipos de dados básicos, se você deseja trabalhar com uma classe, pode se sentir "forçado" a usar o ReadOnly. No entanto, cuidado com a armadilha! ReadOnly significa que você não pode substituir o objeto por outro (você não pode fazer com que ele se refira a outro objeto). Mas qualquer processo que tenha uma referência ao objeto é livre para modificar os valores dentro do objeto!
Portanto, não se confunda ao pensar que o ReadOnly implica que um usuário não pode mudar as coisas. Não há sintaxe simples em C # para impedir que uma instanciação de uma classe altere seus valores internos (tanto quanto eu sei).
fonte
A
const
deve ser codificado , ondereadonly
pode ser definido no construtor da classe.fonte
Há uma diferença notável entre os campos const e somente leitura em C # .Net
const é, por padrão, estático e precisa ser inicializado com valor constante, que não pode ser modificado posteriormente. Mudança de valor também não é permitida em construtores. Não pode ser usado com todos os tipos de dados. Por ex DateTime. Não pode ser usado com o tipo de dados DateTime.
readonly pode ser declarado como estático, mas não necessário. Não há necessidade de inicializar no momento da declaração. Seu valor pode ser atribuído ou alterado usando o construtor. Portanto, oferece vantagem quando usado como membro da classe de instância. Duas instâncias diferentes podem ter um valor diferente do campo somente leitura. Por ex -
Em seguida, o campo somente leitura pode ser inicializado com valores específicos instantâneos, da seguinte maneira:
Aqui, a instância objOne terá o valor do campo somente leitura como 5 e objTwo tem 10. O que não é possível usando const.
fonte
Uma constante será compilada no consumidor como um valor literal, enquanto a sequência estática servirá como uma referência ao valor definido.
Como exercício, tente criar uma biblioteca externa e consumi-la em um aplicativo de console, altere os valores na biblioteca e recompile-a (sem recompilar o programa do consumidor), solte a DLL no diretório e execute o EXE manualmente, você deve encontrar que a cadeia constante não muda.
fonte
Constante
Precisamos fornecer o valor para o campo const quando ele é definido. O compilador salva o valor da constante nos metadados do assembly. Isso significa que uma constante pode ser definida apenas para o tipo primitivo, como booleano, char, byte e assim por diante. As constantes são sempre consideradas membros estáticos, não membros da instância.
Somente leitura
Os campos somente leitura podem ser resolvidos em tempo de execução. Isso significa que podemos definir um valor para um valor usando o construtor para o tipo em que o campo é declarado. A verificação é feita pelo compilador de que os campos somente leitura não são gravados por nenhum método que não seja o construtor.
Mais sobre os dois explicados aqui neste artigo
fonte
Principalmente; você pode atribuir um valor a um campo estático somente leitura a um valor não constante em tempo de execução, enquanto uma const deve ser atribuída a um valor constante.
fonte
Const e somente leitura são semelhantes, mas não são exatamente iguais. Um campo const é uma constante em tempo de compilação, o que significa que esse valor pode ser calculado em tempo de compilação. Um campo somente leitura permite cenários adicionais em que algum código deve ser executado durante a construção do tipo. Após a construção, um campo somente leitura não pode ser alterado.
Por exemplo, membros const podem ser usados para definir membros como:
já que valores como 3,14 e 0 são constantes em tempo de compilação. No entanto, considere o caso em que você define um tipo e deseja fornecer algumas instâncias pré-fabricadas. Por exemplo, você pode definir uma classe Color e fornecer "constantes" para cores comuns, como preto, branco etc. Não é possível fazer isso com membros const, pois o lado direito não é uma constante em tempo de compilação. Pode-se fazer isso com membros estáticos regulares:
mas não há nada que impeça um cliente da Color de trocá-lo, talvez trocando os valores de preto e branco. Escusado será dizer que isso causaria consternação para outros clientes da classe Color. O recurso "somente leitura" aborda esse cenário. Simplesmente introduzindo a palavra-chave readonly nas declarações, preservamos a inicialização flexível e impedimos que o código do cliente mexa.
É interessante notar que os membros const são sempre estáticos, enquanto um membro somente leitura pode ser estático ou não, assim como um campo regular.
É possível usar uma única palavra-chave para esses dois propósitos, mas isso leva a problemas de versão ou de desempenho. Suponhamos por um momento que usamos uma única palavra-chave para isso (const) e um desenvolvedor escreveu:
e um desenvolvedor diferente escreveu um código que contava com A:
Agora, o código gerado pode confiar no fato de que o AC é uma constante em tempo de compilação? Ou seja, o uso de AC pode simplesmente ser substituído pelo valor 0? Se você disser "sim" a isso, isso significa que o desenvolvedor de A não pode mudar a maneira como o CA é inicializado - isso amarra as mãos do desenvolvedor de A sem permissão. Se você disser "não" a esta pergunta, uma otimização importante será perdida. Talvez o autor de A tenha certeza de que AC sempre será zero. O uso de const e readonly permite que o desenvolvedor de A especifique a intenção. Isso contribui para um melhor comportamento de versão e também um melhor desempenho.
fonte
ReadOnly: o valor será inicializado apenas uma vez a partir do construtor da classe.
const: pode ser inicializado em qualquer função, mas apenas uma vez
fonte
A diferença é que o valor de um campo estático somente leitura é definido em tempo de execução, para que ele possa ter um valor diferente para diferentes execuções do programa. No entanto, o valor de um campo const é definido como uma constante de tempo de compilação.
Lembre-se: Para tipos de referência, nos dois casos (estático e instância), o modificador somente leitura impede que você atribua uma nova referência ao campo. Especificamente, não torna imutável o objeto apontado pela referência.
Para obter detalhes, consulte as Perguntas freqüentes em C # sobre este tópico: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx
fonte
Variáveis constantes são declaradas e inicializadas em tempo de compilação. O valor não pode ser alterado após as alas. As variáveis somente leitura serão inicializadas apenas no construtor Static da classe. Somente leitura é usado apenas quando queremos atribuir o valor em tempo de execução.
fonte
Const : valor constante absoluto durante o tempo de vida da aplicação.
Somente leitura : pode ser alterado em tempo de execução.
fonte
Uma coisa a acrescentar ao que as pessoas disseram acima. Se você tiver uma montagem contendo um valor somente leitura (por exemplo, somente MaxFooCount = 4;), poderá alterar o valor que os assemblies chamadores veem enviando uma nova versão dessa montagem com um valor diferente (por exemplo, somente MaxFooCount = 5;)
Mas com uma const, seria dobrada no código do chamador quando o compilador fosse compilado.
Se você atingiu esse nível de proficiência em C #, está pronto para o livro de Bill Wagner, C # efetivo: 50 maneiras específicas de melhorar seu C # O que responde a essa pergunta em detalhes (e 49 outras coisas).
fonte