Pregunta

Estoy luchando cómo utilizar "ref" (para pasar argumentos por referencia) en la aplicación real. Me gustaría tener ejemplo sencillo y sobre todo significativo. Todo lo encontrado hasta ahora podría hacerse de nuevo con facilidad con la adición de tipo de retorno al método. Cualquier idea de alguien? Gracias!

¿Fue útil?

Solución

El mejor ejemplo que viene en mi mente es una función para intercambiar dos valores de las variables:

static void Swap<T>(ref T el1, ref T el2)
{
    var mem = el1;
    el1 = el2;
    el2 = mem;
}

Uso:

static void Main(string[] args)
{
    string a = "Hello";
    string b = "Hi";

    Swap(ref a, ref b);
    // now a = "Hi" b = "Hello"

    // it works also with array values:
    int[] arr = new[] { 1, 2, 3 };
    Swap(ref arr[0], ref arr[2]);
    // now arr = {3,2,1}
}

Una función como ésta, no se puede hacer sin la palabra clave ref.

Otros consejos

Uno de los casos posiblemente esquina ejemplo: Interlocked.Increment . Sin pasar la variable por referencia, no hay forma de realizar el incremento atómicamente.

No se puede decir que he ref utiliza mucho a mí mismo, para ser honesto - Yo por lo general mantenerse alejado de la necesidad de devolver múltiples valores, e incluso entonces out es general suficiente. Muchos de los casos en los que he visto ref utilizado, se ha debido a que el autor no entender cómo se transmiten los argumentos en .NET cuando se trata de los tipos de referencia.

Los métodos TryParse incorporados en el marco son ejemplos típicos. Utilizan out en lugar de ref pero es la misma semántica, es sólo que la persona que llama no tiene que inicializar el valor. Ejemplo:

int result;
bool isSuccess = int.TryParse("some string", out result);
if (isSuccess)
{
    // use the result here
}

Como se puede ver la función devuelve un valor booleano que indica si la operación tiene éxito, pero el resultado real se devuelve como parámetro out.

public static void Main(string args[])
{
    int i=0;
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);


    string mystr = "Hello";
    AddSomeText(ref mystr);
    Console.WriteLine(mystr);


    Console.WriteLine("i = {0}", i);
}


public static void AddSomeText(ref string str)
{
    str+= " World!";
}


public static void AddSomething(ref int ii)
{
    ii+=1;
}

Uno de los lugares más comunes que lo veo, está en Guardar métodos de algunos marcos.

La razón es que en muchos casos no es realmente posible mantener el mismo objeto durante un ahorro de llamadas, si el objeto está siendo serializado a otra máquina y luego regresa como una nueva instancia (tal vez con algunos valores predeterminados adicionales). En ese caso es necesario que el árbitro para que sea obvio que la referencia original ya no es válida.

En cuanto a su necesidad, no puedo llegar a un ejemplo en el que se requeriría. La mayoría de los lugares fuera es muy bien.

creo que un buen ejemplo sería la cama elástica.

Esto es donde se toma una función recursiva y rehacerlo a un método que se llama repeatidly en un conjunto de valores. La razón es que en lugar de entrar en la pila profundamente la pila permanece plana debido a que regrese después de cada llamada en lugar de llamar a sí mismo.

Saludos GJ

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top