Ter um debate amigável com um colega de trabalho sobre isso. Temos algumas ideias sobre isso, mas quer saber o que a multidão do SO pensa sobre isso?
c#
immutability
language-design
readonly
Brian Genisio
fonte
fonte
Respostas:
Um dos motivos é que não há suporte CLR para um local somente leitura. Readonly é traduzido no opcode initonly CLR / CLI. Este sinalizador só pode ser aplicado a campos e não tem significado para um local. Na verdade, aplicá-lo a um local provavelmente produzirá um código não verificável.
Isso não significa que C # não possa fazer isso. Mas daria dois significados diferentes para a mesma construção de linguagem. A versão para locais não teria mapeamento equivalente de CLR.
fonte
readonly
palavra-chave para os campos precisa ser suportada pela CLI porque seu efeito é visível para outros assemblies. Significa apenas que a variável tem apenas uma atribuição no método em tempo de compilação.const
(que em C ++ é mais parecido com C # doreadonly
que com C #const
, embora possa desempenhar ambas as funções). Ainda assim, C ++ oferece suporteconst
para variável automática local. Conseqüentemente, a falta de suporte CLR para um C #readonly
para variável local é irrelevante.using
eout
estão fazendo exatamente isso e o mundo não entrou em colapso.Acho que é um julgamento pobre por parte dos arquitetos C #. o modificador somente leitura em variáveis locais ajuda a manter a correção do programa (assim como afirma) e pode ajudar potencialmente o compilador a otimizar o código (pelo menos no caso de outras linguagens). O fato de não ser permitido no C # agora é outro argumento de que alguns dos "recursos" do C # são meramente uma imposição do estilo de codificação pessoal de seus criadores.
fonte
Respondendo à resposta de Jared, provavelmente teria que ser apenas um recurso de tempo de compilação - o compilador iria proibir você de escrever na variável após a declaração inicial (que teria que incluir uma atribuição).
Posso ver valor nisso? Potencialmente - mas não muito, para ser honesto. Se você não puder dizer facilmente se uma variável será ou não atribuída em outro lugar no método, então seu método é muito longo.
Pelo que vale a pena, Java tem esse recurso (usando o
final
modificador) e muito raramente o vi usado, exceto nos casos em que tem que ser usado para permitir que a variável seja capturada por uma classe interna anônima - e onde ela está usado, dá-me a impressão de desordem em vez de informação útil.fonte
readonly
/final
valores de variáveis com suas palavrasval
-var
chave e . No código Scala, os locaisval
são usados com muita frequência (e são, de fato, preferidos aos locaisvar
). Suspeito que os principais motivos pelos quais ofinal
modificador não é usado com mais frequência em Java são a) desordem eb) preguiça.readonly
não seria muito importante. Por outro lado, para variáveis locais que são usadas em encerramentos,readonly
em muitos casos deixariam o compilador gerar um código mais eficiente. Atualmente, quando a execução entra em um bloco que contém um fechamento, o compilador deve criar um novo objeto heap para as variáveis fechadas, mesmo se nenhum código que usaria o fechamento seja executado . Se uma variável fosse somente leitura, o código fora do encerramento poderia usar uma variável normal; apenas quando um delegado é criado para o encerramento ...Uma proposta somente leitura de locais e parâmetros para foi brevemente discutida pela equipe de design do C # 7. De C # Design Meeting Notes para 21 de janeiro de 2015 :
A discussão continua no repositório C # Language Design. Vote para mostrar seu apoio. https://github.com/dotnet/csharplang/issues/188
fonte
É um descuido para o designer da linguagem c #. F # tem a palavra-chave val e é baseada no CLR. Não há razão para que C # não tenha o mesmo recurso de linguagem.
fonte
Eu era aquele colega de trabalho e não era amigável! (só brincando)
Eu não eliminaria o recurso porque é melhor escrever métodos curtos. É um pouco como dizer que você não deve usar threads porque são difíceis. Dê-me a faca e deixe-me ser responsável por não me cortar.
Pessoalmente, eu queria outra palavra-chave do tipo "var" como "inv" (invariente) ou "rvar" para evitar confusão. Tenho estudado F # recentemente e acho a coisa imutável atraente.
Nunca soube que Java tinha isso.
fonte
Gostaria de variáveis locais somente leitura da mesma maneira que gosto de variáveis locais const . Mas tem menos prioridade do que outros tópicos.
Talvez sua prioridade seja a mesma razão para que os designers de C # (ainda!) Não implementem esse recurso. Mas deve ser fácil (e compatível com versões anteriores) suportar variáveis locais somente leitura em versões futuras.
fonte
Somente leitura significa que o único lugar em que a variável de instância pode ser definida é no construtor. Ao declarar uma variável localmente, ela não tem uma instância (está apenas no escopo) e não pode ser tocada pelo construtor.
fonte
Eu sei, isso não responde o porquê da sua pergunta. De qualquer forma, aqueles que estão lendo esta pergunta podem apreciar o código abaixo.
Se você está realmente preocupado em dar um tiro no próprio pé ao substituir uma variável local que deve ser definida apenas uma vez, e não quer torná-la uma variável mais acessível globalmente, você poderia fazer algo assim.
Exemplo de uso:
Talvez não menos código,
rvar rInt = 5
mas funciona.fonte
Você pode declarar variáveis locais somente leitura em C #, se estiver usando o compilador interativo C #
csi
:Você também pode declarar variáveis locais somente leitura no
.csx
formato de script.fonte
message
não é uma variável aqui, ela é compilada em um campo. Isso não é picuinhas porque a distinção existe claramente no C # interativo também:int x; Console.WriteLine(x)
é C # interativo legal (porquex
é um campo e inicializado implicitamente), masvoid foo() { int x; Console.WriteLine(x); }
não é (porquex
é uma variável e usada antes de ser atribuída). Além disso,Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
revelará quex
é realmente um campo e não uma variável local.c # já tem um var somente leitura, embora em uma sintaxe um pouco diferente:
Considere as seguintes linhas:
Compare com:
É certo que a primeira solução poderia ser menos código para escrever. Mas o segundo fragmento tornará o somente leitura explícito, ao fazer referência à variável.
fonte
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.usar
const
palavra-chave para tornar a variável somente leitura.referência: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
fonte
const
onde a variável só pode ser atribuída durante sua inicialização - não no estilo csharp,const
onde apenas expressões de tempo de compilação podem ser usadas. Por exemplo, você não pode fazer,const object c = new object();
mas umreadonly
local permitiria que você fizesse isso.Acho que é porque uma função que tem uma variável somente leitura pode nunca ser chamada, e provavelmente há algo sobre ela saindo do escopo, e quando você precisaria?
fonte