Tener un debate amistoso con un compañero de trabajo sobre esto. Tenemos algunas ideas sobre esto, pero nos preguntamos qué piensa la gente de SO sobre esto.
c#
immutability
language-design
readonly
Brian Genisio
fuente
fuente
Respuestas:
Una razón es que no hay soporte CLR para un local de solo lectura. Readonly se traduce en el código de operación de inicio CLR / CLI. Esta bandera solo se puede aplicar a 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 daría dos significados diferentes a la misma construcción del lenguaje. La versión para locales no tendría un mapeo equivalente a CLR.
fuente
readonly
CLI debe admitir la palabra clave para campos porque su efecto es visible para otros ensamblados. Todo lo que significaría es que la variable solo tiene una asignación en el método en el momento de la compilación.const
(que en C ++ se parece más a C #readonly
que a C #const
, aunque puede desempeñar ambos roles). Sin embargo, C ++ admiteconst
variables automáticas locales. Por lo tanto, la falta de compatibilidad con CLR para C #readonly
para la variable local es irrelevante.using
yout
están haciendo exactamente eso y el mundo no se derrumbó.Creo que es un mal juicio por parte de los arquitectos de C #. El modificador de solo lectura en las variables locales ayuda a mantener la corrección del programa (como afirma) y puede ayudar potencialmente al compilador a optimizar el código (al menos en el caso de otros lenguajes). 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 imposición del estilo de codificación personal de sus creadores.
fuente
Al abordar la respuesta de Jared, probablemente solo tendría que ser una función en tiempo de compilación: el compilador le prohibiría escribir en la variable después de la declaración inicial (que tendría que incluir una asignación).
¿Puedo ver valor en esto? Potencialmente, pero no mucho, para ser honesto. Si no puede saber fácilmente si se asignará una variable en otro lugar del método, entonces su método es demasiado largo.
Por lo que vale, Java tiene esta característica (usando el
final
modificador) y muy pocas veces la he visto usada excepto en los casos en los que tiene que usarse para permitir que la variable sea capturada por una clase interna anónima, y dónde está usado, me da una impresión de desorden en lugar de información útil.fuente
readonly
/ localesfinal
de las variables con sus palabras claveval
yvar
. En el código de Scala, los mensajes de correo electrónico localesval
se utilizan con mucha frecuencia (y, de hecho, se prefieren a losvar
mensajes de correo electrónico locales ). Sospecho que las razones principales por las que elfinal
modificador no se usa con más frecuencia en Java son a) el desorden yb) la pereza.readonly
no sería demasiado importante. Por otro lado, para las variables locales que se utilizan en cierres,readonly
en muchos casos permitiría al compilador generar código más eficiente. Actualmente, cuando la ejecución entra en un bloque que contiene un cierre, el compilador debe crear un nuevo objeto de montón para las variables cerradas, incluso si nunca se ejecuta ningún código que usaría el cierre . Si una variable fuera de solo lectura, el código fuera del cierre podría usar una variable normal; solo cuando se crea un delegado para el cierre ...El equipo de diseño de C # 7 discutió brevemente una propuesta de solo lectura local y parámetros . De C # Design Meeting Notes para el 21 de enero de 2015 :
La discusión continúa en el repositorio de diseño del lenguaje C #. Vote para mostrar su apoyo. https://github.com/dotnet/csharplang/issues/188
fuente
Es un descuido del diseñador del lenguaje C #. F # tiene la palabra clave val y se basa en CLR. No hay ninguna razón por la que C # no pueda tener la misma característica de idioma.
fuente
¡Yo era ese compañero de trabajo y no era amigable! (es una 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 palabra clave de tipo "var" como "inv" (invariante) o "rvar" para evitar el desorden. He estado estudiando F # últimamente y encuentro atractivo lo inmutable.
Nunca supe que Java tenía esto.
fuente
Me gustaría variables de solo lectura locales de la misma manera que me gustan las variables de const locales . Pero tiene menos prioridad que otros temas.
Tal vez su prioridad sea la misma razón por la que los diseñadores de C # no implementan (¡todavía!) Esta característica. Pero debería ser fácil (y compatible con versiones anteriores) admitir variables de solo lectura locales en versiones futuras.
fuente
Solo lectura significa que el único lugar donde se puede establecer la variable de instancia es en el constructor. Cuando se declara una variable localmente, no tiene una instancia (solo está en el alcance) y el constructor no puede tocarla.
fuente
Lo sé, esto no responde al por qué de tu pregunta. De todos modos, aquellos que lean esta pregunta podrían apreciar el código a continuación.
Si realmente le preocupa dispararse a sí mismo en el pie al anular una variable local que solo debe establecerse una vez, y no desea convertirla en una variable más accesible globalmente, podría hacer algo como esto.
Uso de ejemplo:
Quizás no menos código,
rvar rInt = 5
pero funciona.fuente
Puede declarar variables locales de solo lectura en C #, si está utilizando el compilador interactivo de C #
csi
:También puede declarar variables locales de solo lectura en el
.csx
formato de script.fuente
message
aquí no hay una variable, se compila en un campo. Esto no es quisquilloso porque la distinción también existe claramente en C # interactivo:int x; Console.WriteLine(x)
es C # interactivo legal (porquex
es un campo e implícitamente inicializado) perovoid foo() { int x; Console.WriteLine(x); }
no lo es (porquex
es una variable y se usa antes de ser asignada). Además,Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
revelará quex
realmente es un campo y no una variable local.c # ya tiene una var de solo lectura, aunque en una sintaxis algo diferente:
Considere las siguientes líneas:
Comparar con:
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.
fuente
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.utilizar
const
palabra clave para hacer una variable de solo lectura.referencia: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
fuente
const
donde la variable solo se puede asignar durante su inicialización, no en el estilo csharp,const
donde solo se pueden usar expresiones en tiempo de compilación. Por ejemplo, no puede hacerlo,const object c = new object();
pero unreadonly
local le permitiría hacerlo.Creo que eso se debe a que es posible que nunca se llame a una función que tiene una variable de solo lectura, y es probable que haya algo acerca de que se salga del alcance, y ¿cuándo debería hacerlo?
fuente