Pergunta

Eu notei algo peculiar sobre o Visual Studio. Primeiro, tente digitar isto (C #) em algum lugar em uma função:

class Foo  
{  
    public void Bar()  
    {  
        string s;
        int i = s.Length;
    }
}

Agora, imediatamente ele vai marcar o s em s.Length como um erro, dizendo "Use of unassigned local variable 's'". Por outro lado, tente este código:

class Foo  
{  
    private string s;
    public void Bar()  
    {  
        int i = s.Length;
    }
}

Ele irá compilar e salientam a s em private string s com um aviso, dizendo que "Field 'Foo.s' is never assigned to, and will always have its default value null".

Agora, se VS é que inteligente e sabe que s sempre será nulo, por que não é um erro para obter seu comprimento no segundo exemplo? Meu palpite original, "Ele só dá um erro de compilação, se o compilador simplesmente não pode completar o seu trabalho. Uma vez que o código é executado tecnicamente, desde que você nunca chamar Bar (), é apenas um aviso." Só que a explicação é invalidada pelo primeiro exemplo. Você ainda pode executar o código sem erro, desde que você nunca chamar Bar (). Então, o que dá? Apenas um descuido, ou estou faltando alguma coisa?

Foi útil?

Solução

O primeiro exemplo (o erro) é um exemplo de do compilador rastreamento definida-atribuição e que só é aplicada a variáveis ??locais. Devido ao contexto limitado, o compilador tem uma aderência hermética sobre esta situação. Note-se que s não é nulo, ele é indefinido.

No segundo exemplo, é um campo s (e o padrão é nulo). Não há erro do compilador, mas ele vai sempre ser pego em tempo de execução. Neste caso particular poderia ser preso, mas esse tipo de erro não está na detectável geral pelo compilador.
Por exemplo, você pode adicionar um Bar2() método que atribui uma string para s mas chamá-lo mais tarde do que Bar(), ou não em todos. Isso eliminaria a advertência, mas não o erro de execução.

Por isso, é por design.

Outras dicas

Para o segundo exemplo, o código é válido apenas pode não funcionar corretamente. Aqui estão vários casos em que este programa poderia executar "com sucesso"

  • O compilador não é 100% correto. É possível que "S" para ter um valor não nulo se uma instância é modificado através da reflexão.
  • O programa pode executar sem erro se o método Bar não é sempre chamado
  • Este programa poderia ser um programa de teste que está provocando uma NullReferenceException para testar motivos

A única acho que eu posso fazer é que no segundo exemplo, s poderia ser mudado através da reflexão (usando BindingFlags.Private para acessar o membro privado).

Na primeira amostra s é uma variável local e compilador pode easialy verifique se s varible não foi atribuído antes de ser utilizado.

No segundo, s é uma variável global e é possível que ele foi inicializado em outro lugar em uma classe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top