Eu li sobre const
e static readonly
campos. Temos algumas classes que contêm apenas valores constantes. Usado para várias coisas em nosso sistema. Então, eu estou querendo saber se minha observação está correta:
static readonly
Esse tipo de valor constante deve sempre ser para tudo o que é público? E usar apenas const
para valores internos / protegidos / privados?
O que você recomenda? Talvez eu não deva usar static readonly
campos, mas talvez use propriedades talvez?
static readonly
: tente usar uma const dentro de umaIEnumerator
que desencadeie uma irrecuperávelyield
e você obterá um temido "erro interno do compilador" . Não testei o código fora do Unity3D, mas confio que seja um bug mono ou .NET . É uma questão de c # , no entanto.static readonly
não pode ser usado naswitch-case
instrução comocase
variável,const
é necessário para esse fim.static readonly
não pode ser usado como parâmetro atributo tambémRespostas:
public static readonly
campos são um pouco incomuns;public static
propriedades (com apenas aget
) seriam mais comuns (talvez apoiadas por umprivate static readonly
campo).const
os valores são gravados diretamente no site da chamada; isto é de dois gumes:Se o valor nunca mudar, const estará
Zero
correto - etc, faça considerações razoáveis; p Fora isso, asstatic
propriedades são mais comuns.fonte
readonly
campos não podem ser usados nas instruções switch / case, você precisa que sejamconst
.Eu usaria
static readonly
se o consumidor estivesse em uma montagem diferente. Ter oconst
e o consumidor em duas montagens diferentes é uma boa maneira de dar um tiro no próprio pé .fonte
internal const
oupublic static readonly
dependendo da visibilidade desejada.public const
(por exemplo, qualquer parte de um padrão. Sempre que trabalho com XML, há um namespaces com um monte depublic const string
.) Mas, em geral,public const
só deve ser usado depois de considerar as implicações corretamente.Poucas coisas mais relevantes a serem observadas:
const int a
readonly int a
fonte
ctor
único.Este é apenas um complemento para as outras respostas. Não os repetirei (agora quatro anos depois).
Existem situações em que a
const
e um não-const têm semântica diferente. Por exemplo:imprime
True
, enquanto:escreve
False
.O motivo é que o método
x.Equals
possui duas sobrecargas, uma que aceita umshort
(System.Int16
) e outra que aceita umobject
(System.Object
). Agora, a questão é se um ou ambos se aplicam ao meuy
argumento.Quando
y
é uma constante em tempo de compilação (literal),const
torna-se importante que exista uma conversão implícita deint
para,short
desde queint
seja uma constante, e desde que o compilador C # verifique se seu valor está dentro do intervalo de ashort
( qual42
é). Consulte Conversões implícitas de expressão constante na Especificação de idioma do C #. Portanto, as duas sobrecargas devem ser consideradas. A sobrecargaEquals(short)
é preferida (qualquershort
um éobject
, mas nem todosobject
sãoshort
). Então,y
é convertido emshort
e essa sobrecarga é usada. EntãoEquals
compara doisshort
de valor idêntico, e isso dátrue
.Quando
y
não é uma constante, não existe conversão implícita deint
parashort
. Isso ocorre porque, em geral, umint
pode ser grande demais para caber em umshort
. (Existe uma conversão explícita , mas eu não disseEquals((short)y)
, portanto isso não é relevante.) Vemos que apenas uma sobrecarga se aplica, aEquals(object)
única. Entãoy
está na caixa paraobject
. Então,Equals
você comparará aSystem.Int16
aSystem.Int32
e, como os tipos de tempo de execução nem sequer concordam, isso renderáfalse
.Concluímos que, em alguns casos (raros), alterar um
const
membro do tipo para umstatic readonly
campo (ou de outra forma, quando possível) pode alterar o comportamento do programa.fonte
short x = 42;
legal. Porque aí você tem umint
, ou seja, o literal42
, que é implicitamente transformado emshort x
. Mas então, eles podem ter restringido isso a apenas literais numéricos; no entanto, eles escolheram permitir também coisas comoshort x = y;
ondey
é definido comoconst int y = 42;
e depois acabaram com isso.Uma coisa a notar é que const é restrito a tipos primitivos / de valor (a exceção são as strings)
fonte
const
poderia ser utilizado para outros tipos também, exceto que ele tem de ser inicializado como nulo, o que torna inútil :)System.Exception
? :)const
podem ser utilizadas, sãosbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
,bool
, acrescido de quaisquerenum
tipos.const
não pode ser usado para outros tipos de valor, comoDateTime
ouTimeSpan
ouBigInteger
. Também não pode ser usado para aIntPtr
struct (considerado um tipo "primitivo" por alguns; o termo tipo primitivo é confuso em C #). ↵↵const
Pode ser usado para todos os tipos de referência . Se o tipo forstring
, qualquer valor de sequência poderá ser especificado. Caso contrário, o valor deve sernull
.const
usandodefault
. Parastruct
tipos, é uma instância com todos os seus membros configurados para os valores padrão.Somente leitura estática : o valor pode ser alterado por meio de
static
construtor em tempo de execução. Mas não através da função membro.Constante : Por padrão
static
. O valor não pode ser alterado de qualquer lugar (Ctor, Função, tempo de execução etc, não-onde).Somente leitura : o valor pode ser alterado através do construtor em tempo de execução. Mas não através da função membro.
Você pode dar uma olhada no meu repositório: tipos de propriedade C # .
fonte
A
readonly
palavra-chave é diferente daconst
palavra - chave. Umconst
campo só pode ser inicializado na declaração do campo. Umreadonly
campo pode ser inicializado na declaração ou em um construtor. Portanto, osreadonly
campos podem ter valores diferentes, dependendo do construtor usado. Além disso, enquanto umconst
campo é uma constante em tempo de compilação, oreadonly
campo pode ser usado para constantes de tempo de execuçãoReferência curta e clara do MSDN aqui
fonte
const
ereadonly
são semelhantes, mas não são exatamente iguais.Um
const
campo é uma constante em tempo de compilação, o que significa que esse valor pode ser calculado em tempo de compilação. Umreadonly
campo permite cenários adicionais em que algum código deve ser executado durante a construção do tipo. Após a construção, umreadonly
campo não pode ser alterado.Por exemplo, os
const
membros podem ser usados para definir membros como:Como 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:
Porém, 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 o
readonly
palavra chave 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
Minha preferência é usar const sempre que possível, o que, como mencionado acima, se limita a expressões literais ou a algo que não requer avaliação.
Se eu me deparar com essa limitação, recorro à estática somente leitura , com uma ressalva. Geralmente, eu usaria uma propriedade estática pública com um getter e um campo estático privado de backup, conforme Marc menciona aqui .
fonte
Referencia: c-sharpcorner
fonte
Um campo estático somente leitura é vantajoso ao expor a outros assemblies um valor que pode ser alterado em uma versão posterior.
Por exemplo, suponha que a montagem
X
exponha uma constante da seguinte maneira:Se a montagem
Y
referenciarX
e usar essa constante, o valor 2.3 será inserido na montagemY
quando compilado. Isso significa que, seX
mais tarde for recompilado com a constante definida como 2.4,Y
ainda usará o valor antigo de 2.3 até queY
seja recompilado. Um campo estático somente leitura evita esse problema.Outra maneira de analisar isso é que qualquer valor que possa mudar no futuro não é constante por definição e, portanto, não deve ser representado como um.
fonte
const:
somente leitura:
fonte
Const : os valores das variáveis const precisam definir junto com a declaração e depois disso não será alterado. const são implicitamente estáticos, portanto, sem criar instância de classe, podemos acessá-los. isso tem um valor em tempo de compilação
ReadOnly : valores de variável readonly que podemos definir ao declarar e também ao usar o construtor em tempo de execução. variáveis readonly não podem acessar sem instância de classe.
Static readonly : valores de variável estática readonly que podemos definir ao declarar, bem como apenas através do construtor estático, mas não com qualquer outro construtor. Essas variáveis também podemos acessar sem criar instância de classe (como variáveis estáticas).
readonly estático será a melhor escolha se tivermos que consumir as variáveis em diferentes montagens. Verifique os detalhes completos no link abaixo
https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/
fonte
Há uma pequena diferença entre os campos const e estático somente leitura em C # .Net
const deve ser inicializado com valor em tempo de compilação.
const é, por padrão, estático e precisa ser inicializado com valor constante, que não pode ser modificado posteriormente. 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 uma vez. Portanto, existe a possibilidade de alterar o valor do campo somente leitura uma vez (não importa, se é estático ou não), o que não é possível com const.
fonte
Constantes são como o nome indica, campos que não mudam e geralmente são definidos estaticamente em tempo de compilação no código.
Variáveis somente leitura são campos que podem ser alterados sob condições específicas.
Eles podem ser inicializados quando você os declara como uma constante, mas geralmente são inicializados durante a construção do objeto dentro do construtor.
Eles não podem ser alterados após a inicialização, nas condições mencionadas acima.
Somente leitura estática soa como uma má escolha para mim, pois, se é estático e nunca muda, use-o public const; se puder mudar, não será uma constante e, dependendo de suas necessidades, você poderá usar a leitura -só ou apenas uma variável regular.
Além disso, outra distinção importante é que uma constante pertence à classe, enquanto a variável somente leitura pertence à instância!
fonte
Uma const (sendo determinada em tempo de compilação) pode ser usada nos casos em que uma estática somente leitura não pode, como em instruções switch, ou construtores de atributos. Isso ocorre porque os campos somente leitura são resolvidos apenas em tempo de execução e algumas construções de código exigem garantia de tempo de compilação. Uma estática somente leitura pode ser calculada em um construtor, o que geralmente é uma coisa essencial e útil. A diferença é funcional, como deve ser o uso deles na minha opinião.
Em termos de alocação de memória, pelo menos com seqüências de caracteres (sendo um tipo de referência), parece não haver diferença, pois ambas são internadas e farão referência à instância internada.
Pessoalmente, meu padrão é apenas estático, pois faz mais sentido semântico e lógico para mim, principalmente porque a maioria dos valores não é necessária no momento da compilação. E, a propósito, as estáticas públicas somente para leitura não são incomuns ou incomuns, como afirma a resposta marcada: por exemplo,
System.String.Empty
é uma.fonte
Outra diferença entre declarar const e static readonly está na alocação de memória.
Um campo estático pertence ao tipo de um objeto e não a uma instância desse tipo. Como resultado, uma vez que a classe é referenciada pela primeira vez, o campo estático "permanece" na memória pelo resto do tempo, e a mesma instância do campo estático é referenciada por todas as instâncias do tipo.
Por outro lado, um campo const "pertence a uma instância do tipo.
Se a memória da desalocação for mais importante para você, prefira usar const . Se velocidade, use estática somente leitura .
fonte