2009-02-09 20 views
14

Las referencias en C# son bastante similares a las de C++, excepto que son basura recolectada.¿Por qué C# no ofrece constness similar a C++?

¿Por qué es entonces tan difícil para el compilador de C# para apoyar lo siguiente:

  1. Miembros funciones marcadas const.
  2. Referencias a tipos de datos (que no sean cadenas) marcados const, a través de los cuales solo se pueden llamar las funciones miembro const?

Creo que sería muy útil si C# lo admite. Por un lado, realmente ayudará al abandono gay aparentemente generalizado con el que los programadores de C# devuelven referencias desnudas a datos privados (al menos eso es lo que he visto en mi lugar de trabajo).

¿O ya hay algo equivalente en C# que me falta? (Sé acerca de las palabras clave readonly y const, pero en realidad no sirven para el propósito anterior)

Respuesta

17

Sospecho que hay algunas razones prácticas, y algunas razones teóricas:

  • caso de que el constness aplicar al objeto o la referencia? Si está en la referencia, ¿debería ser solo en tiempo de compilación o como un bit dentro de la referencia misma? ¿Puede algo más que tiene una referencia no const al mismo objeto violín debajo del capó?
  • ¿Le gustaría poder rechazarlo como sea posible en C++? Eso no suena muy parecido a algo que quieras en una plataforma administrada ... ¿pero qué hay de todos esos momentos en los que tiene sentido en C++?
  • La sintaxis se vuelve complicada (IMO) cuando tiene más de un tipo involucrado en una declaración: piense en matrices, genéricos, etc. Puede ser difícil determinar con exactitud qué bit es const.
  • Si no puede rechazarlo, todos deben hacerlo bien. En otras palabras, tanto los tipos de marcos de .NET como cualquier otra biblioteca de terceros que use, todos tienen que hacer lo correcto, o le quedan situaciones desagradables en las que su código no puede hacer lo correcto debido a un problema sutil con constness.

Hay una grande en cuanto a por qué no se puede apoyar ahora sin embargo:

  • Compatibilidad hacia atrás: no hay manera de todas las bibliotecas se pueden migrar correctamente a la misma, por lo que es más o menos inútil :(

estoy de acuerdo que sería útil contar con algún tipo de indicador constness, pero no puedo ver que pasa, me temo.

EDITAR: Ha habido una discusión sobre este furor en la comunidad de Java durante siglos. Hay un montón de comentarios sobre el relevant bug que pueden resultarle interesantes.

+0

Gracias Jon. Eso es iluminador. –

0

La pregunta es, ¿necesitamos constness en C#?

  1. Estoy bastante seguro de que el jitter sabe que el método dado no va a afectar al propio objeto y realiza optimizaciones correspondiente automágicamente. (Tal vez mediante la emisión de call en lugar de callvirt?)

  2. no estoy seguro de que necesitamos esos, ya que la mayoría de las ventajas de rendimiento constness son relacionados, se termina en el punto 1.

Además de eso, C# tiene la palabra clave readonly.

+1

No estoy de acuerdo con su afirmación de que "la mayoría de los pros de la constness están relacionados con el rendimiento" - Yo diría que la mayoría están relacionados con la corrección y la mantenibilidad. –

+2

No es para conveniencia de JITter, sino para el programador. En C++, si intento modificar un objeto const, el compilador me da un error. Entonces, por ejemplo, puedo devolver referencias de mis métodos. En C# todo el mundo parece estar devolviendo referencias que cualquier persona externa puede cambiar. ¡Peligroso! –

+0

@Frederick: Exactamente :) –

6

Como Jon ya está cubierto (por supuesto) const correctness no es tan simple como podría parecer. C++ lo hace de una manera. D lo hace de otra manera (posiblemente más correcta/útil). C# coquetea con él, pero no hace nada más atrevido, como habrás descubierto (y probablemente nunca bien, ya que Jon volvió a cubrirse).

Dicho esto, creo que muchas de las "razones teóricas" de Jon se resuelven en el modelo de D's.

En D (2.0), const funciona de forma muy parecida a C++, excepto que es totalmente transitiva (por lo que se aplicaría a un puntero al objeto apuntado, cualquier miembro de ese objeto, cualquier puntero que ese objeto tuviera, objetos apuntaban a etc.), pero es explícito que este solo aplica a partir de la variable que ha declarado const (por lo que si ya tiene un objeto no const y toma un puntero const a él, la variable no const puede todavía mutar el estado).

D introduce otra palabra clave - invariante - que se aplica al objeto en sí. Esto significa que nada puede cambiar el estado una vez inicializado.

La belleza de esta disposición es que un método const puede aceptar tanto objetos const como invariantes. Dado que los objetos invariables son el pan y la mantequilla del mundo funcional, y el método const se puede marcar como "puro" en el sentido funcional, incluso aunque se pueda usar con objetos mutables.

Volviendo a la pista: creo que es el caso de que solo ahora (la segunda mitad de las travesuras) comprendamos la mejor forma de usar const (e invariante). .Net se definió originalmente cuando las cosas eran más confusas, por lo que no se comprometió demasiado, y ahora es demasiado tarde para actualizar.

Me encanta ver a un puerto de D corrida contra el .Net VM, aunque :-)

2

No me sorprendería si se añadieran tipos inmutables a una versión futura de C#. Ya ha habido movimientos en esa dirección con C# 3.0.

Los tipos anónimos, por ejemplo, son inmutables.

Creo que, como resultado de las extensiones diseñadas para adoptar el paralelismo, es probable que vea cada vez más la inmutabilidad.

Cuestiones relacionadas