Pergunta

Ter um debate amigável com um colega de trabalho sobre isso. Temos algumas idéias sobre isso, mas se perguntando o que a multidão SO pensa sobre isso?

Foi útil?

Solução

Uma das razões é que não há suporte CLR para um readonly local. Readonly é traduzido para o CLR / código de operação initonly CLI. Esta bandeira só pode ser aplicada aos campos e não tem significado para um local. Na verdade, aplicando-à uma vontade locais prováveis ??produzir código não verificado.

Isto não significa que C # não poderia fazer isso. Mas daria dois significados diferentes para a mesma construção da linguagem. A versão para os habitantes locais não teria nenhum mapeamento equivalente CLR.

Outras dicas

Eu acho que é um julgamento pobre na parte de C # arquitetos. readonly modificador de variáveis ??locais ajuda a manter programa de correção (como afirma) e pode, potencialmente, ajudar o código compilador optimize (pelo menos no caso de outras línguas). O fato de que ele é anulado em C # agora, é outro argumento que algumas das "características" de C # são apenas uma aplicação de estilo de codificação pessoal de seus criadores.

Dirigindo-se a resposta de Jared, ele provavelmente apenas tem que ser um recurso em tempo de compilação -. O compilador iria proibi-lo de escrever para a variável após a declaração inicial (que teria de incluir uma atribuição)

Posso ver valor nisso? Potencialmente - mas não muito, para ser honesto. Se você não pode facilmente dizer se ou não uma variável que vai ser atribuído em outras partes do método, em seguida, seu método é muito longo.

Por que vale a pena, Java tem esta característica (usando o modificador final) e eu tenho muito raramente vi sendo utilizado excepto em casos em que tem para ser usado para permitir que a variável a ser capturado por uma classe interna anônima -. e onde é usado, ele me dá uma impressão de desordem em vez de informações úteis

A proposta locals somente leitura e parâmetros para foi brevemente discutido pelo C # equipa 7 design. De C # Design Notas de reuniões para 21 de janeiro de 2015 :

Parâmetros e moradores podem ser capturados por lambdas e, assim, acessado simultaneamente, mas não há nenhuma maneira de protegê-los de problemas de mútuo estatais compartilhada:. Eles não podem ser somente leitura

Em geral, a maioria dos parâmetros e muitos moradores estão nunca pretendeu ser atribuído a depois que começam o seu valor inicial. Permitindo somente leitura sobre eles diria que a intenção clara.

Um problema é que esse recurso pode ser um "incômodo atraente". Considerando que a "coisa certa" a fazer seria quase sempre para fazer parâmetros e moradores readonly, seria encher o código significativamente a fazê-lo.

Uma idéia a parcialmente aliviar este é permitir que a combinação readonly var em uma variável local a ser contratada para val ou algo curto assim. De modo mais geral, poderíamos tentar pensar simplesmente de uma palavra-chave mais curto do que o estabelecido somente leitura para expressar a-ness somente leitura.

Discussão continua no repo C # linguagem de design. Votar para mostrar seu apoio. https://github.com/dotnet/csharplang/issues/188

eu era aquele colega de trabalho e não foi amigável! (Brincadeirinha)

Eu não eliminaria o recurso porque é melhor para escrever métodos curtos. É um pouco como dizer que você não deve usar tópicos, porque eles são difíceis. Dá-me a faca e me deixar ser responsável por não me cortando.

Pessoalmente, eu queria outro "var" tipo de palavra-chave como "inv" (invarient) ou "rvar" a desordem evitar. Venho estudando F # como de tarde e encontrar a coisa imutável atraente.

Nunca soube Java tinha isso.

Gostaria locais somente leitura variáveis ??da mesma forma como eu gosto local, const variáveis. Mas ele tem menos prioridade do que outros tópicos.
Talvez a sua prioridade é a mesma razão para C # designers para não (ainda!) implementar este recurso. Mas ele deve ser fácil (e compatível) para apoiar variáveis ??somente leitura locais em versões futuras.

É um descuido para o designer c # idioma. F # tem val palavra-chave e é baseado em CLR. Não há nenhuma razão C # não podem ter o mesmo recurso de linguagem.

Readonly significa o único lugar a variável de instância pode ser definido é no construtor. Ao declarar uma variável local não tem uma instância (que é apenas no escopo), e não pode ser tocado pelo construtor.

Eu sei, isto não responde a isso a sua pergunta. De qualquer forma, aqueles que estão lendo esta questão pode apreciar o código abaixo, no entanto.

Se você está realmente preocupado com tiro a sua auto no pé ao substituir uma variável local que só deve ser definido uma vez, e você não deseja torná-lo uma variável mais globalmente acessível, você poderia fazer algo parecido com isso.

    public class ReadOnly<T>
    {
        public T Value { get; private set; }

        public ReadOnly(T pValue)
        {
            Value = pValue;
        }

        public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
        {
            if (object.ReferenceEquals(pReadOnlyT, null))
            {
                return object.ReferenceEquals(pT, null);
            }
            return (pReadOnlyT.Value.Equals(pT));
        }

        public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
        {
            return !(pReadOnlyT == pT);
        }
    }

Exemplo de utilização:

        var rInt = new ReadOnly<int>(5);
        if (rInt == 5)
        {
            //Int is 5 indeed
        }
        var copyValueOfInt = rInt.Value;
        //rInt.Value = 6; //Doesn't compile, setter is private

Talvez não como código menos como rvar rInt = 5 mas funciona.

Você pode declarar variáveis ??somente leitura locais em C #, se você estiver usando o C # csi compilador interativo:

>"C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.

Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)

Você também pode declarar variáveis ??somente leitura locais no formato de roteiro .csx.

c # já tem uma var somente leitura, embora em uma sintaxe um pouco diferente:

Considere as seguintes linhas:

var mutable = myImmutableCalculationMethod();
readonly var immutable = mutable; // not allowed in C# 8 and prior versions
return immutable;

Compare com:

var mutable = myImmutableCalculationMethod();
string immutable() => mutable; // allowed in C# 7
return immutable();

É certo que a primeira solução poderia ser menos código para escrever. Mas o segundo trecho vai fazer o readonly explícito, ao fazer referência à variável.

Eu acho que é porque uma função que tem uma variável de somente leitura não podem ser chamados, e provavelmente há algo sobre ele que vai fora do escopo, e quando você precisa?

uso const palavra-chave para fazer somente leitura variável.

referência: https://docs.microsoft .com / en-us / dotnet / csharp / de referência a linguagem / palavras-chave / const

public class SealedTest
{
    static void Main()
    {
        const int c = 707;
        Console.WriteLine("My local constant = {0}", c);
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top