2010-04-25 8 views
5

Aquí es mi clase:Problemas con la palabra clave ref. Pregunta muy novato!

public class UserInformation 
    { 
     public string Username { get; set; } 
     public string ComputerName { get; set; } 
     public string Workgroup { get; set; } 

     public string OperatingSystem { get; set; } 
     public string Processor { get; set; } 
     public string RAM { get; set; } 
     public string IPAddress { get; set; } 

     public UserInformation GetUserInformation() 
     { 
      var CompleteInformation = new UserInformation(); 

      GetPersonalDetails(ref CompleteInformation); 
      GetMachineDetails(ref CompleteInformation); 

      return CompleteInformation; 
     } 

     private void GetPersonalDetails(ref UserInformation CompleteInformation) 
     { 

     } 

     private void GetMachineDetails(ref UserInformation CompleteInformation) 
     { 

     } 
    } 

estoy bajo la impresión de que la palabra clave ref indica a la computadora para usar la misma variable y no crear uno nuevo.

¿Lo estoy usando correctamente? ¿Tengo que usar la referencia tanto en la línea de código de llamada como en la implementación del método real?

Respuesta

5

Cuando se pasa un tipo de referencia (en su caso, su clase UserInformation es un tipo de referencia) como un parámetro, por defecto está de paso el puntero a la clase por valor, es decir, el GetPersonalDetails conseguiría su propia copia de un puntero que apunta a la misma instancia de la clase UserInformation.

Al usar la palabra clave ref en su ejemplo, pasará el mismo puntero a la instancia UserInformation del método.

Así, en su caso, si su intención es sencillo modificar las propiedades de UserInformation, la palabra clave ref No es necesario, ya que va modificando la instancia actual de GetPersonalDetails y GetMachineDetails. Sin embargo, si su intención es instanciar un nuevo objeto UserInformation desde esos métodos o configurar la instancia como nula, deberá usar la palabra clave ref.

Jon Skeet hace un gran trabajo al explicar el paso de parámetros en this article.

4

Probablemente no necesite usar ref aquí. Las clases son tipos de referencia, por lo que ya está aprobando una referencia.

Aquí está tu código sin ref y una serie de otros problemas de estilo fija:

public UserInformation GetUserInformation() 
    { 
     UserInformation userInformation = new UserInformation(); 

     updatePersonalDetails(userInformation); 
     updateMachineDetails(userInformation); 

     return userInformation; 
    } 

    private void updatePersonalDetails(UserInformation userInformation) 
    { 
     userInformation.FirstName = "Sergio"; 
     userInformation.LastName = "Tapia"; 
    } 

    private void updateMachineDetails(UserInformation userInformation) 
    { 
     userInformation.MachineName = "Foobar"; 
    } 
+0

Derecha. La única vez que necesita usar ref para un objeto de clase es si quiere decir foo = somethingElse. – ojrac

+0

¿Puede elaborar por favor? ¿Puede mostrarme mi código sin usar ref para que funcione como lo tengo ahora? ¡Estoy ansioso por aprender! –

+0

@Sergio: Su código no hace nada ... ¿qué quiere decir con "trabajar como lo tengo ahora"? –

0

A diferencia de C++, C# paso variable de referencia a una función significa usar la misma variable. Esto significa que puede cambiar la variable y este cambio es visible para la persona que llama. La palabra clave ref permite cambiar la referencia en sí misma (esto significa que la referencia se pasa por referencia). Esto significa que la función puede establecer una referencia a nulo o asignarlo a otro objeto, y este cambio es visible para la persona que llama. Sí, ref se debe usar tanto por la función como por la persona que llama. Esto es mejor que en C++, puede ver en un código de llamada, ese parámetro se pasa por referencia.

Si conoce C/C++, pasar el tipo de referencia a la función sin la palabra clave ref es lo mismo que * en C++. Pasar el tipo de referencia a la función con ref es el mismo que ** en C++.

3

estoy bajo la impresión de que la palabra clave ref indica a la computadora para usar la misma variable y no crear un nuevo uno.

Quizás tenga C background. A diferencia de C class/struct, la clase C# no hace una copia de toda la clase a la función llamada. Si va a usar struct en C#, hará una copia independiente de todo el contenido de struct a la función llamada, por lo que ref se garantiza cuando quiera minimizar la memoria/tiempo de ejecución al pasar su estructura de datos struct a su función.

Si usted tiene conocimiento en C, el código anterior se traduce en:

UserInformation *CompleteInformation = new UserInformation(); 

GetPersonalDetails(&CompleteInformation);  

Y su función que tiene ref traduce en lo siguiente:

void GetPersonalDetails(UserInformation **CompleteInformation) 
{ 
    // you can make the CompleteInformation outside to point to new instance 
} 

Así que si no va a señalar CompleteInformation de nuevo instancia dentro de GetPersonalDetails, no es necesario usar la palabra clave ref. Elimine la palabra clave ref en el enunciado de llamada y la función llamada.

var CompleteInformation = new UserInformation(); 
GetMachineDetails(CompleteInformation); 

private void GetPersonalDetails(UserInformation CompleteInformation) 
{ 
    // you cannot make the CompleteInformation outside to point to new instance 
} 

Ese código C# se traduce a C como:

UserInformation *CompleteInformation = new UserInformation(); 

GetPersonalDetails(CompleteInformation);  

void GetPersonalDetails(UserInformation *CompleteInformation) 
{ 
    // you cannot make the CompleteInformation outside to point to new instance 
} 

Hmm .. :-) sigue pensando cómo explicar mi respuesta en términos enteros de C#, no haciendo una analogía con C. Pensamiento.

Cuestiones relacionadas