referencia por pasar pasaje parametros parametro objetos funciones entre diferencia como clase argumentos c# ref

por - Cuándo usar ref y cuándo no es necesario en C#



pasar objetos como parametros en c# (8)

Como received_s es una matriz, está pasando un puntero a esa matriz. La función manipula los datos existentes en su lugar, sin cambiar la ubicación o el puntero subyacente. La palabra clave ref significa que está pasando el puntero real a la ubicación y actualizando ese puntero en la función externa, por lo que el valor en la función externa cambiará.

Por ejemplo, la matriz de bytes es un puntero a la misma memoria antes y después, la memoria acaba de actualizarse.

La referencia de punto final realmente está actualizando el puntero al punto final en la función externa a una nueva instancia generada dentro de la función.

Tengo un objeto que es mi estado de memoria en el programa y también tengo algunas otras funciones de trabajo a las que le paso el objeto para modificar el estado. Lo he estado pasando por ref a las funciones del trabajador. Sin embargo, me encontré con la siguiente función.

byte[] received_s = new byte[2048]; IPEndPoint tmpIpEndPoint = new IPEndPoint(IPAddress.Any, UdpPort_msg); EndPoint remoteEP = (tmpIpEndPoint); int sz = soUdp_msg.ReceiveFrom(received_s, ref remoteEP);

Me confunde porque tanto remoteEP como remoteEP devuelven cosas desde la función. ¿Por qué remoteEP necesita una ref y received_s no?

También soy programador de ca, así que estoy teniendo problemas para sacarme los indicadores de mi cabeza.

Editar: parece que los objetos en C # son punteros para el objeto debajo del capó. Por lo tanto, cuando pasa un objeto a una función, puede modificar los contenidos del objeto a través del puntero y lo único que se le pasa a la función es el puntero al objeto para que el objeto no se copie. Utilice ref o out si desea poder cambiar o crear un nuevo objeto en la función que sea como un doble puntero.


La regla de cero en primer lugar, los primitivos se pasan por valor (pila) y no primitivo por referencia (montón) en el contexto de TIPOS involucrados.

Los parámetros involucrados pasan por valor de forma predeterminada. Buen post que explica las cosas en detalle. http://yoda.arachsys.com/csharp/parameters.html

Student myStudent = new Student {Name="A",RollNo=1}; ChangeName(myStudent); static void ChangeName(Student s1) { s1.Name = "Z"; // myStudent.Name will also change from A to Z // {AS s1 and myStudent both refers to same Heap(Memory) //Student being the non-Primitive type } ChangeNameVersion2(ref myStudent); static void ChangeNameVersion2(ref Student s1) { s1.Name = "Z"; // Not any difference {same as **ChangeName**} } static void ChangeNameVersion3(ref Student s1) { s1 = new Student{Name="Champ"}; // reference(myStudent) will also point toward this new Object having new memory // previous mystudent memory will be released as it is not pointed by any object }

Podemos decir (con advertencia) que los tipos no primitivos no son más que Punteros Y cuando los pasamos por ref podemos decir que estamos pasando el Puntero Doble


Piense en un parámetro que no sea ref como un puntero y un parámetro ref como un doble puntero. Esto me ayudó más.

Casi nunca debería pasar valores por ref. Sospecho que si no fuera por cuestiones de interoperabilidad, el equipo de .Net nunca lo habría incluido en la especificación original. La manera OO de lidiar con la mayoría de los problemas que resuelven los parámetros de ref es:

Para valores de retorno múltiples

  • Crear estructuras que representan los valores de retorno múltiples

Para las primitivas que cambian en un método como resultado de la llamada al método (el método tiene efectos secundarios en los parámetros primitivos)

  • Implemente el método en un objeto como un método de instancia y manipule el estado del objeto (no los parámetros) como parte de la llamada al método
  • Use la solución de valor de retorno múltiple y combine los valores devueltos con su estado
  • Cree un objeto que contenga un estado que pueda ser manipulado por un método y pase ese objeto como el parámetro, y no las primitivas.

Piense en una referencia que significa que está pasando un puntero por referencia. No usar una referencia significa que está pasando un puntero por valor.

Mejor aún, ignore lo que acabo de decir (es probable que sea engañoso, especialmente con tipos de valores) y lea esta página de MSDN .


Probablemente puedas escribir una aplicación C # completa y nunca pasar objetos / estructuras por ref.

Tuve un profesor que me dijo esto:

El único lugar donde usarías refs es donde:

  1. Quiere pasar un objeto grande (es decir, los objetos / struct tiene objetos / estructuras dentro de él a múltiples niveles) y copiarlo sería costoso y
  2. Está llamando a un Framework, API de Windows u otra API que lo requiera.

No lo hagas solo porque puedes. Puedes cometer errores en algunos asquerosos errores si comienzas a cambiar los valores en un param y no le prestas atención.

Estoy de acuerdo con su consejo, y en mis más de cinco años desde la escuela, nunca tuve la necesidad de hacerlo, aparte de llamar al Marco o la API de Windows.


Respuesta corta: lea mi artículo sobre la aprobación de argumentos .

Respuesta larga: cuando un parámetro de tipo de referencia se pasa por valor, solo se pasa la referencia, no una copia del objeto. Esto es como pasar un puntero (por valor) en C o C ++. La persona que llama no verá los cambios en el valor del parámetro en sí, pero los cambios en el objeto al que apunta la referencia se verán.

Cuando un parámetro (de cualquier tipo) se pasa por referencia, eso significa que el llamador ve cualquier cambio en el parámetro; los cambios en el parámetro son cambios en la variable.

El artículo explica todo esto con más detalle, por supuesto :)

Respuesta útil: casi nunca necesita usar ref / out . Básicamente es una forma de obtener otro valor de retorno, y generalmente se debe evitar precisamente porque significa que el método probablemente esté tratando de hacer demasiado. Ese no es siempre el caso ( TryParse etc. son los ejemplos canónicos de uso razonable de out ) pero usar ref / out debería ser una rareza relativa.


Según entiendo, todos los objetos derivados de la clase Object se pasan como punteros, mientras que los ordinarios (int, struct) no se pasan como punteros y requieren ref. No estoy seguro de la cadena (¿se deriva en última instancia de la clase Object?)


Si bien estoy de acuerdo con la respuesta general de Jon Skeet y algunas de las otras respuestas, hay un caso de uso para usar ref , y eso es para reforzar las optimizaciones de rendimiento. Se ha observado durante el perfilado de rendimiento que establecer el valor de retorno de un método tiene ligeras implicaciones de rendimiento, mientras que usar ref como argumento por el que el valor de retorno se rellena en ese parámetro da como resultado que se elimine este ligero cuello de botella.

Esto es realmente útil solo cuando los esfuerzos de optimización se llevan a niveles extremos, sacrificando la legibilidad y quizás la capacidad de prueba y el mantenimiento para ahorrar milisegundos o quizás milisegundos divididos.