Pregunta

Tener un debate amistoso con un compañero de trabajo sobre esto. Tenemos algunas ideas sobre esto, pero nos preguntamos qué piensa la multitud SO sobre esto.

¿Fue útil?

Solución

Una razón es que no hay soporte CLR para un local de solo lectura. Readonly se traduce al CLR / CLI initonly opcode. Esta bandera solo se puede aplicar a los campos y no tiene significado para un local. De hecho, aplicarlo a un local probablemente producirá un código no verificable.

Esto no significa que C # no pueda hacer esto. Pero le daría dos significados diferentes a la misma construcción del lenguaje. La versión para locales no tendría una asignación de CLR equivalente.

Otros consejos

Creo que es un juicio pobre por parte de los arquitectos de C #. El modificador de solo lectura en las variables locales ayuda a mantener la corrección del programa (al igual que las afirmaciones) y potencialmente puede ayudar al compilador a optimizar el código (al menos en el caso de otros idiomas). El hecho de que no esté permitido en C # en este momento, es otro argumento de que algunas de las '' características '' de C # son simplemente una aplicación del estilo de codificación personal de sus creadores.

Dirigiendo la respuesta de Jared, probablemente solo tendría que ser una función de tiempo de compilación: el compilador le prohibiría escribir en la variable después de la declaración inicial (que debería incluir una asignación).

¿Puedo ver valor en esto? Potencialmente, pero no mucho, para ser honesto. Si no puede determinar fácilmente si una variable se asignará o no a otra parte del método, entonces su método es demasiado largo.

Para lo que vale, Java tiene esta característica (usando el modificador final ) y muy rara vez he visto que se usara excepto en los casos en que tiene que se utilizará para permitir que la variable sea capturada por una clase interna anónima, y ??donde se usa , me da una impresión de desorden en lugar de información útil.

Una propuesta locales y parámetros de solo lectura fue discutido brevemente por el equipo de diseño de C # 7. De C # Design Meeting Notes para el 21 de enero de 2015 :

  

Los parámetros y los locales pueden ser capturados por lambdas y, por lo tanto, acceder a ellos simultáneamente, pero no hay forma de protegerlos de problemas de estado mutuo compartido: no pueden ser de solo lectura.

     

En general, la mayoría de los parámetros y muchos locales nunca deben asignarse después de obtener su valor inicial. Permitir solo lectura en ellos expresaría esa intención claramente.

     

Un problema es que esta característica podría ser una molestia atractiva. Mientras que "lo correcto" hacer casi siempre sería hacer que los parámetros y los locales sean de solo lectura, desordenaría significativamente el código para hacerlo.

     

Una idea para aliviar esto en parte es permitir que la combinación readonly var en una variable local se contraiga a val o algo así. En términos más generales, podríamos tratar de pensar simplemente en una palabra clave más corta que la de solo lectura establecida para expresar la solo lectura.

La discusión continúa en el repositorio de diseño de lenguaje C #. Vote para mostrar su apoyo. https://github.com/dotnet/csharplang/issues/188

¡Era ese compañero de trabajo y no era amigable! (es broma)

No eliminaría la función porque es mejor escribir métodos cortos. Es un poco como decir que no deberías usar hilos porque son difíciles. Dame el cuchillo y déjame ser responsable de no cortarme.

Personalmente, quería otra " var " escriba la palabra clave como " inv " (invariante) o " rvar " para evitar el desorden. Últimamente he estado estudiando F # y encuentro atractivo lo inmutable.

Nunca supe que Java tenía esto.

Me gustaría que las variables locales de solo lectura de la misma manera que me gustan las variables locales const . Pero tiene menos prioridad que otros temas.
Tal vez su prioridad sea la misma razón para que los diseñadores de C # no (¡todavía!) implementen esta función. Pero debería ser fácil (y compatible con versiones anteriores) admitir variables locales de solo lectura en futuras versiones.

Es un descuido para el diseñador de lenguaje C #. F # tiene una palabra clave val y se basa en CLR. No hay ninguna razón por la que C # no pueda tener la misma función de lenguaje.

Solo lectura significa que el único lugar donde se puede establecer la variable de instancia es en el constructor. Al declarar una variable localmente, no tiene una instancia (solo está dentro del alcance) y el constructor no puede tocarla.

Lo sé, esto no responde el por qué a tu pregunta. De todos modos, aquellos que lean esta pregunta pueden apreciar el código a continuación.

Si realmente le preocupa dispararse en el pie al anular una variable local que solo debe establecerse una vez, y no desea que sea una variable más accesible a nivel mundial, podría hacer algo como esto.

    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);
        }
    }

Ejemplo de uso:

        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

Tal vez no sea menos código que rvar rInt = 5 pero funciona.

Puede declarar variables locales de solo lectura en C #, si está utilizando el compilador interactivo de C # csi :

>"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)

También puede declarar variables locales de solo lectura en el formato de script .csx .

c # ya tiene una var de solo lectura, aunque con una sintaxis algo diferente:

Considere las siguientes líneas:

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

Comparar con:

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

Es cierto que la primera solución podría ser menos código para escribir. Pero el segundo fragmento hará que la lectura sea explícita, al hacer referencia a la variable.

Creo que es porque una función que tiene una variable de solo lectura nunca se puede invocar, y probablemente haya algo fuera de alcance, y ¿cuándo lo necesitarías?

use la palabra clave const para hacer que la variable sea de solo lectura.

referencia: https://docs.microsoft .com / es-es / dotnet / csharp / language-reference / keywords / const

public class SealedTest
{
    static void Main()
    {
        const int c = 707;
        Console.WriteLine("My local constant = {0}", c);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top