He leído que .NET admite el retorno de referencias, pero C # no. ¿Hay alguna razón especial? Por qué no puedo hacer algo como:
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
c#
.net
reference
return-type
Tom Sarduy
fuente
fuente
return ref x
C# 7
:)Respuestas:
Esta pregunta fue el tema de mi blog el 23 de junio de 2011 . Gracias por la gran pregunta!
El equipo de C # está considerando esto para C # 7. Vea https://github.com/dotnet/roslyn/issues/5233 para más detalles.
ACTUALIZACIÓN: ¡La función llegó a C # 7!
Estás en lo correcto; .NET admite métodos que devuelven referencias administradas a variables. .NET también admite variables locales que contienen referencias administradas a otras variables. (Sin embargo, tenga en cuenta que .NET no admite campos o matrices que contengan referencias administradas a otras variables porque eso complica demasiado la historia de recolección de basura. Además, los tipos de "referencia administrada a variables" no son convertibles en objetos y, por lo tanto, no pueden usarse como escriba argumentos para tipos o métodos genéricos).
El comentarista "RPM1984" por alguna razón solicitó una cita para este hecho. RPM1984 Le animo a leer la especificación CLI Partición I Sección 8.2.1.1, "Punteros administrados y tipos relacionados" para obtener información sobre esta característica de .NET.
Es completamente posible crear una versión de C # que admita ambas funciones. Entonces podrías hacer cosas como
y luego llamarlo con
Sé empíricamente que es posible construir una versión de C # que admita estas características porque lo he hecho . Los programadores avanzados, particularmente las personas que portan código C ++ no administrado, a menudo nos solicitan más capacidad similar a C ++ para hacer cosas con referencias sin tener que sacar el gran martillo de usar punteros y fijar memoria en todo el lugar. Al usar referencias administradas, obtiene estos beneficios sin pagar el costo de arruinar el rendimiento de su recolección de basura.
Hemos considerado esta característica y, de hecho, la hemos implementado lo suficiente como para mostrarla a otros equipos internos para obtener sus comentarios. Sin embargo, en este momento, según nuestra investigación , creemos que la función no tiene un atractivo suficientemente amplio o casos de uso convincentes para convertirla en una función de lenguaje real compatible . Tenemos otras prioridades más altas y una cantidad limitada de tiempo y esfuerzo disponible, por lo que no vamos a hacer esta función en el corto plazo.
Además, hacerlo correctamente requeriría algunos cambios en el CLR. En este momento, el CLR trata los métodos de devolución de devolución como legales pero no verificables porque no tenemos un detector que detecte esta situación:
M3 devuelve el contenido de la variable local de M2, ¡pero la vida útil de esa variable ha terminado! Es posible escribir un detector que determine los usos de devoluciones de referencia que claramente no violan la seguridad de la pila. Lo que haríamos sería escribir dicho detector, y si el detector no pudiera demostrar la seguridad de la pila, entonces no permitiríamos el uso de devoluciones de referencia en esa parte del programa. No es una gran cantidad de trabajo de desarrollo hacerlo, pero es una gran carga para los equipos de prueba asegurarse de que realmente tenemos todos los casos. Es solo otra cosa que aumenta el costo de la función hasta el punto de que en este momento los beneficios no superan los costos.
Si puede describirme por qué quiere esta función, realmente lo agradecería . Cuanta más información tengamos de clientes reales sobre por qué lo quieren, más probabilidades habrá de que llegue al producto algún día. Es una pequeña característica linda y me gustaría poder llegar a los clientes de alguna manera si hay suficiente interés.
(Ver también preguntas relacionadas ¿Es posible devolver una referencia a una variable en C #? Y ¿Puedo utilizar una referencia dentro de una función C # como C ++? )
fuente
y
vida después de regresarM2
? Esperaría que esta característica funcione como lambdas capturando locales. ¿O es el comportamiento que propuso porque es cómo CLR maneja ese escenario?Estás hablando de métodos que devuelven una referencia a un tipo de valor. El único ejemplo incorporado en C # que conozco es el array-accessor de un tipo de valor:
y ahora crea una matriz de esa estructura:
En este caso
points[0]
, el indexador de matrices está devolviendo una referencia a struct. Es imposible escribir su propio indexador (por ejemplo, para una colección personalizada), que tiene el mismo comportamiento de "devolver una referencia".No diseñé el lenguaje C #, así que no sé todo el razonamiento detrás de no admitirlo, pero creo que la respuesta corta podría ser: podemos llevarnos bien sin él.
fuente
Siempre puedes hacer algo como:
fuente
C # 7.0 tiene soporte para devolver referencias. Mira mi respuesta aquí .
fuente