¿Por qué C # tiene tanto out y ref?

18

C # tiene las palabras clave outy ref. ¿Por qué se requieren estos dos? Descargo de responsabilidad: no tengo un conocimiento profundo de C #.

Neo
fuente
3
¿No hay un duplicado entre sitios en Stack Overflow?
Peter Mortensen
2
¿Estás preguntando por la diferencia entre refy out? ¿O se pregunta cuál es el uso de los argumentos por referencia ref/ outen comparación con los argumentos por valor (sin modificador del parámetro)? ¿O ambos?
Jeppe Stig Nielsen
1
Siento que esta pregunta es similar, pero no del todo, al menos si se toma desde la perspectiva del diseño del lenguaje
jmoreno

Respuestas:

32

En cuanto a la implementación, son esencialmente lo mismo, pero outcomunican algo que refno lo hace: a usted no le importan las entradas. Esto significa ciertas cosas para usted y para las herramientas. Por ejemplo, puede pasar una variable no inicializada a un outparámetro y eso no es un problema, de lo contrario sería, y dentro de la función debe asignar un valor al outparámetro antes de que regrese, mientras que no es necesario hacer nada en Todo con un refvalor.

Mason Wheeler
fuente
10
Ref vs out es mucho más importante para el compilador que para un programador. El compilador está obligado a asegurarse de que no lee una variable antes de que se le asigne un valor, y outle da una manera de hacerlo que mejor coincida con la forma en que desea tratar las variables en primer lugar.
Cort Ammon - Restablece a Mónica
¿Podría por favor dar más detalles sobre: ​​'out' comunica algo que 'ref' no hace?
Neo
44
@Neo: Básicamente lo que dije en la respuesta: comunica que no te importa usar esto como entrada y, por lo tanto, es seguro pasar un valor no inicializado a un outparámetro porque la función que lo recibe no va a leerlo .
Mason Wheeler
@MasonWheeler ¿Sin embargo, esto está permitido (y / o impuesto en el extremo receptor)? Fuera es solo un atributo, internamente.
Random832
@ Random832: como Robert publicó bajo su respuesta, eche un vistazo a Eric Lippert (ex compilador de C #) discutiendo esto en stackoverflow.com/q/2876315
Mason Wheeler
7

Para comprender estas dos palabras clave, deberá comprender qué significa pasar un valor por referencia . Esencialmente significa que, si modifica la variable de parámetro que pasa dentro del método o función, esa variable retiene su valor modificado cuando finaliza su función. Declarar un parámetro como refo outlogra esto, mientras que una variable de parámetro ordinaria retendría su valor original, incluso si lo modificara en la función.

La única diferencia entre refy outes que outno requiere que inicialice la variable antes de pasarla a la función, pero refsí; mientras que out hace que tenga que ceder algo a la variable dentro de la función, pero refno lo hace.

Robert Harvey
fuente
¿No hay una diferencia relacionada con la varianza?
monocell
Vea la respuesta de Eric Lippert en stackoverflow.com/q/2876315
Robert Harvey
2

Tu preguntaste.

C # tiene y ref, por qué estos dos son obligatorios No tengo un conocimiento profundo de C #. ¿Por qué se requieren los parámetros out y ref?

Y la respuesta es que no son OBLIGATORIAS, por ejemplo, Java tampoco tiene y VB solo tiene ref (y solo lo requiere en la declaración del método).

Puede escribir fácilmente un programa completo sin usar ninguno.

Existen porque ocasionalmente son útiles. Es por eso que hay dos de ellos y no solo uno, porque es útil hacer la distinción entre 'aquí hay algo, modificarlo si quieres' y 'darle un nuevo valor a esta cosa'.

Otros idiomas tienen prioridades diferentes y, por lo tanto, pueden incluir o no estos o equivalentes. Incluso pueden estar en desacuerdo sobre si alguno es útil, por lo que pueden decidir activamente NO implementar uno u otro.

jmoreno
fuente
1

En su esencia tanto refy outproporcionar un mecanismo para pasar la dirección de una variable a un método para que pueda ser actualizado - asignar a la refo outparámetro actualiza la variable en el contexto del llamador. Donde difieren es en las garantías: outgarantiza que la variable se actualizará, refno.

Desde el otro lado de la llamada hay diferencias similares. outNo se garantiza que un parámetro de nuestro método contenga nada útil a la llegada y debe establecerse en un valor en algún momento, mientras refque se puede suponer que un parámetro tiene un valor y no necesitamos hacer nada específico con él.

Esta diferencia tiene un impacto en el análisis, la generación y la optimización del código que, aunque no es muy evidente para nosotros la mayor parte del tiempo, puede tener algunos efectos en la forma en que nuestros programas terminan operando. El generador de código puede diferir la asignación de la variable hasta inmediatamente antes de la llamada, el optimizador puede decidir que puede reordenar algunas operaciones de manera más efectiva en función del contrato, etc.

En términos de uso: como regla general, lo uso outpara situaciones en las que no me importa el contenido de la variable cuando llega como parámetro y refcuando lo hago.

Corey
fuente