Problemas para usar la palabra clave ref. pregunta muy novato!
Pregunta
Aquí está mi clase:
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.
Am I utilizando correctamente? ¿Tengo que usar ref tanto en la línea de código que llama y la implementación del método actual?
Solución
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
haría obtener su propia copia de un puntero que apunta a la mismo instancia de la clase UserInformation
.
El uso de la palabra clave en su ejemplo ref
pasará el mismo puntero a la UserInformation
instance al método.
Así pues, 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 crear una instancia de un nuevo objeto UserInformation
desde el interior de esos métodos o establecer la instancia a nulo, que tendría que utilizar la palabra clave ref
.
Jon Skeet hace un gran trabajo de explicar el paso de parámetros en este artículo .
Otros consejos
Probablemente no es necesario el uso ref
aquí. Las clases son los tipos de referencia, por lo que ya está pasando una referencia.
Esta es su código sin ref
y una serie de otros problemas de estilo fijo:
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";
}
Estoy bajo la impresión de que el árbitro palabra clave indica a la computadora para utilizar el misma variable y no crean una nueva uno.
Tal vez usted tiene C fondo. A diferencia de clase C / estructura, clase C # no hace una copia de toda la clase a la función llamada. Si va a utilizar struct en C #, se hará una copia independiente del contenido de toda la estructura a la función llamada, por lo que se justifica ref cuando se desea reducir al mínimo la memoria / tiempo de ejecución de gastos generales al pasar sus struct de datos estructura a su función.
Si usted tiene conocimiento en C, el código anterior se traduce a:
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 apuntar a CompleteInformation nueva instancia dentro de GetPersonalDetails, sin necesidad de utilizar la palabra clave ref. Retire la palabra clave ref en la declaración y llamada función que llama.
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 ..
A diferencia de C ++, C # en pasar variable de referencia a unos medios de función utilizando la misma variable. Este medio, se puede cambiar la variable y este cambio es visible para la persona que llama. Ref palabra clave permite a sí misma referencia de cambio (es decir, la referencia se pasa por referencia). Esto significa, función puede ajustar la referencia a NULL o asignar a otro objeto, y este cambio es visible para la persona que llama. Sí, ref debe ser utilizado tanto por la función y la persona que llama. Esto es mejor que en C ++, se puede ver en un código de llamada, ese parámetro se pasa por referencia.
Si conoce C / C ++, pasando tipo de referencia a la función sin ref palabra clave es la misma que en C ++ *. Pasando tipo de referencia para la función con ref es el mismo que ** en C ++.