No .Net, por que String.Empty é somente leitura em vez de uma constante? Só estou imaginando se alguém sabe qual foi o raciocínio por trás dessa decisão.
No .Net, por que String.Empty é somente leitura em vez de uma constante? Só estou imaginando se alguém sabe qual foi o raciocínio por trás dessa decisão.
Respostas:
O motivo static readonly
usado em vez de const
deve-se ao uso com código não gerenciado, conforme indicado pela Microsoft aqui na versão Common Source Infrastructure 2.0 de versão compartilhada . O arquivo para analisar é sscli20\clr\src\bcl\system\string.cs
.
A constante Vazia mantém o valor da sequência vazia. Precisamos chamar o construtor String para que o compilador não marque isso como literal.
Marcar isso como literal significaria que ele não aparece como um campo que podemos acessar do nativo.
Encontrei essas informações neste artigo útil no CodeProject .
String.Empty
mais apenas por esse motivo.
Eu acho que há muita confusão e respostas ruins aqui.
Primeiro de tudo, os const
campos são static
membros ( não membros da instância ).
Verifique a seção 10.4 Constantes da especificação da linguagem C #.
Mesmo que as constantes sejam consideradas membros estáticos, uma declaração constante não requer nem permite um modificador estático.
Se os public const
membros são estáticos, não se pode considerar que uma constante criará um novo objeto.
Diante disso, as seguintes linhas de código fazem exatamente a mesma coisa com relação à criação de um novo Objeto.
public static readonly string Empty = "";
public const string Empty = "";
Aqui está uma observação da Microsoft que explica a diferença entre os 2:
A palavra-chave readonly é diferente da palavra-chave const. Um campo const só pode ser inicializado na declaração do campo. Um campo somente leitura pode ser inicializado na declaração ou em um construtor. Portanto, os campos somente leitura podem ter valores diferentes, dependendo do construtor usado. Além disso, enquanto um campo const é uma constante em tempo de compilação, o campo somente leitura pode ser usado para constantes de tempo de execução, ...
Então, acho que a única resposta plausível aqui é a de Jeff Yates.
const string
e static readonly string
faço a mesma coisa. Os valores const são substituídos no código vinculado, enquanto os valores estáticos somente leitura são referenciados. Se você tiver uma const
biblioteca A usada pela biblioteca B, a biblioteca B substituirá todas as referências a essa const
variável por seu valor literal; se essa variável fosse static readonly
substituída, seria referenciada e seu valor determinado em tempo de execução.
String.Empty read only instead of a constant?
Se você tornar qualquer string constante , o compilador será substituído pela string realmente todos os lugares que você chamar e você preencherá seu código com a mesma string todo e, quando o código for executado, também será necessário ler repetidamente essa string da memória diferente dados.
Se você deixar sua string de leitura apenas em um lugar, pois é a String.Empty
, o programa manterá a mesma string apenas em um local e a lerá, ou fará referência a ela - mantendo os dados na memória mínimos.
Além disso, se você compilar qualquer dll usando o String.Empty como const e, por qualquer motivo, o String.Empty for alterado, a dll compilada não funcionará mais da mesma maneira, porque o cost
cria o código interno para realmente manter uma cópia da string em todas as chamadas.
Veja este código por exemplo:
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
virá pelo compilador como:
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
e a chamada de montagem
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
Editar: erro de digitação corrigido
Esta resposta existe para fins históricos.
Originalmente:
Porque String
é uma classe e, portanto, não pode ser uma constante.
Discussão estendida:
Muitos diálogos úteis foram elaborados ao examinar esta resposta e, em vez de excluí-la, esse conteúdo é reproduzido diretamente:
No .NET, (ao contrário de Java), string e String são exatamente iguais. E sim, você pode ter constantes literais de cadeia de caracteres no .net - DrJokepu
Você está dizendo que uma classe não pode ter constantes? #: 226 StingyJack às 16:58
Sim, os objetos precisam usar somente leitura. Somente estruturas podem fazer constantes. Eu acho que quando você usa, em
string
vez doString
compilador, muda a const para um somente leitura para você. Tudo relacionado a manter os programadores em C felizes. - Garry Shutler 03/02/09 às 16:59tvanfosson apenas explicou um pouco mais detalhadamente. "X não pode ser uma constante, porque o Y que contém é uma classe" era um pouco livre de contexto demais;) #: 1128 Leonidas
string.Empty é uma propriedade estática que retorna uma instância da classe String, ou seja, a string vazia, não a própria classe de string. - tvanfosson 03/02/09 às 17:01
Vazio é uma instância somente leitura (não é uma propriedade) da classe String. #: 314 senfo às 17:02
Cabeça doendo. Ainda acho que estou certo, mas agora tenho menos certeza. Pesquisa necessária hoje à noite! Garry Shutler / Fev 3 '09 às 17:07
A cadeia vazia é uma instância da classe de cadeia. Vazio é um campo estático (não uma propriedade, estou corrigido) na classe String. Basicamente, a diferença entre um ponteiro e o que ele aponta. Se não fosse somente leitura, poderíamos mudar a qual instância o campo Vazio se refere. #: 23410 tvanfosson às 17:07
Garry, você não precisa fazer nenhuma pesquisa. Pense nisso. String é uma classe. Vazio é uma instância de uma String. #: 314 senfo às 17:12
Há algo que ainda não entendi: como diabos o construtor estático da classe String pode criar uma instância da classe String? Não é algum tipo de cenário de "galinha ou ovo"? #: 28411 DrJokepu 17:12 5
Esta resposta estaria correta para quase qualquer outra classe, exceto System.String. O .NET faz muito caso especial de desempenho para seqüências de caracteres, e uma delas é que você PODE ter constantes de seqüência de caracteres, apenas tente. Nesse caso, Jeff Yates tem a resposta correta. Joel Mueller Feb 3 '09 às 19:25
Conforme descrito em §7.18, uma expressão constante é uma expressão que pode ser totalmente avaliada em tempo de compilação. Como a única maneira de criar um valor não nulo de um tipo de referência que não seja string é aplicar o novo operador e, como o novo operador não é permitido em uma expressão constante, o único valor possível para constantes dos tipos de referência diferente de string é nulo. Os dois comentários anteriores foram retirados diretamente da especificação da linguagem C # e reiteram o que Joel Mueller mencionou. - senfo 04/02/09 às 15:05 5