.net Por que não é String.Empty uma constante?




readonly constants (4)

Eu acho que há muita confusão e más respostas aqui.

Primeiro de tudo, os campos const são membros static ( 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 de constante não requer nem permite um modificador estático.

Se public const membros public const forem estáticos, não se pode considerar que uma constante criará um novo objeto.

Dado isso, as seguintes linhas de código fazem exatamente a mesma coisa em relação à criação de um novo objeto.

public static readonly string Empty = "";
public const string Empty = "";

Aqui está uma nota da Microsoft que explica a diferença entre o 2:

A palavra-chave readonly é diferente da palavra-chave const. Um campo const só pode ser inicializado na declaração do campo. Um campo readonly pode ser inicializado na declaração ou em um construtor. Portanto, campos readonly podem ter valores diferentes dependendo do construtor usado. Além disso, enquanto um campo const é uma constante de tempo de compilação, o campo readonly pode ser usado para constantes de tempo de execução, ...

Então, acho que a única resposta plausível aqui é a de Jeff Yates.

Em .Net porque é que String.Empty só lê em vez de uma constante? Eu só estou querendo saber se alguém sabe o que o raciocínio estava por trás dessa decisão.


String.Empty read only instead of a constant?

Se você fizer qualquer string constante , então o compilador é substituído pela string atual em todos os lugares e você preenche seu código com a mesma string toda e quando o código é executado também é necessário ler de novo e de novo aquela string da memória diferente dados.

Se você deixar sua string somente em um lugar, como é String.Empty , o programa mantém a mesma string em um lugar e a lê, ou se refere a ela - mantendo os dados na memória no mínimo.

Além disso, se você compilar qualquer dll usando o String.Empty como const, e por qualquer motivo, a alteração String.Empty, em seguida, a dll compilada não funcionará mais o mesmo, porque o cost fazer o código interno para realmente manter uma cópia do 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;    
    }
}

Será vindo 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 da assembléia

        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


O motivo pelo qual a static readonly é usada em vez de const deve ser usado com código não gerenciado, conforme indicado pela Microsoft aqui na versão 2.0 do Common Source Common Language Infrastructure . O arquivo a ser sscli20\clr\src\bcl\system\string.cs é sscli20\clr\src\bcl\system\string.cs .

A constante vazia mantém o valor da string vazia. Precisamos chamar o construtor String para que o compilador não marque isso como um literal.

Marcar isso como um literal significaria que ele não aparece como um campo que podemos acessar nativo.

Eu encontrei esta informação deste artigo acessível no CodeProject .


Essa resposta existe para fins históricos.

Originalmente:

Porque String é uma classe e, portanto, não pode ser uma constante.

Discussão Extendida:

Um monte de diálogos úteis foi elaborado para avaliar essa resposta e, em vez de excluí-la, esse conteúdo é reproduzido diretamente:

No .NET, (diferente de Java), string e String são exatamente os mesmos. E sim, você pode ter constantes literais de string no .net - DrJokepu

Você está dizendo que uma classe não pode ter constantes? #: 4709 StingyJack

Sim, os objetos precisam usar somente leitura. Apenas estruturas podem fazer constantes. Eu acho que quando você usa string vez de String o compilador altera o const em um readonly para você. Tudo a ver com manter os programadores C felizes. #: 567 Garry Shutler Garry Shutler at 16:59

O tvanfosson acabou de explicar um pouco mais detalhadamente. "X não pode ser uma constante, porque o contendo Y é uma classe" era apenas um pouco livre de contexto;) #: 29762 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. #: 4704 tvanfosson

Empty é uma instância readonly (não é uma propriedade) da classe String. - senfo em 17:02.

Cabeça doendo. Eu ainda acho que estou certo, mas agora estou menos certo. Pesquisa exigida esta noite! Garry Shutler às 17:07

A string vazia é uma instância da classe string. Empty é um campo estático (não uma propriedade, eu estou corrigido) na classe String. Basicamente, a diferença entre um ponteiro e a coisa para a qual ele aponta. Se não fosse somente leitura, poderíamos alterar a instância à qual o campo Vazio se refere. #: 4702 tvanfosson

Garry, você não precisa fazer nenhuma pesquisa. Pense nisso. String é uma classe. Vazio é uma instância de uma String. - senfo às 17:12

Há algo que eu não entendo: como é que o construtor estático da classe String pode criar uma instância da classe String? Isso não é algum tipo de cenário de "galinha ou ovo"? - DrJokepu 5 de julho de 2009 às 17:12 5

Essa resposta seria correta para quase qualquer outra classe, mas System.String. O .NET faz um monte de performance de invólucro especial para strings, e uma delas é que você pode ter constantes de strings, apenas tente. Neste caso, Jeff Yates tem a resposta correta. #: 5402 Joel Mueller

Conforme descrito no §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 diferente de 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 de 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 4f09 'em 15:05





constants