这是我的班级:
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)
{
}
}
我的印象是ref关键字告诉计算机使用相同的变量而不是创建新的变量。
我正确使用它吗?我是否必须在调用代码行和实际方法实现上使用ref?
答案 0 :(得分:5)
当您将引用类型(在您的情况下,您的UserInformation
类是引用类型)作为参数传递时,默认情况下您将指针传递给类按值,意味着GetPersonalDetails
将获得自己的指针副本,该指针指向UserInformation
类的相同实例。
在示例中使用ref
关键字会将指向UserInformation
实例的相同指针传递给方法。
因此,在您的情况下,如果您的目的是简单地修改UserInformation
的属性,则不需要ref
关键字,因为您将从GetPersonalDetails
修改实际实例, GetMachineDetails
。但是,如果您的目的是从这些方法中实例化新的UserInformation
对象或将实例设置为null,则需要使用ref
关键字。
Jon Skeet可以很好地解释this article中的参数传递。
答案 1 :(得分:4)
您可能不需要在此使用ref
。类是引用类型,因此您已经传递了引用。
这是您的代码没有ref
并且修复了许多其他样式问题:
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";
}
答案 2 :(得分:3)
我的印象是参考 关键字告诉计算机使用 相同的变量,而不是创建一个新的 之一。
也许你有C背景。与C类/结构不同,C#类不会将整个类的副本复制到被调用的函数。如果你将在C#中使用struct,它会将struct的整个内容的独立副本复制到被调用的函数,因此当你想在传递 struct 数据时最小化内存/运行时开销时,保证ref是合理的结构到你的功能。
如果您对C有所了解,则上述代码将转换为:
UserInformation *CompleteInformation = new UserInformation();
GetPersonalDetails(&CompleteInformation);
你的函数有ref转换为:
void GetPersonalDetails(UserInformation **CompleteInformation)
{
// you can make the CompleteInformation outside to point to new instance
}
因此,如果您不将CompleteInformation指向GetPersonalDetails中的新实例,则无需使用ref关键字。删除调用语句和被调用函数的ref关键字。
var CompleteInformation = new UserInformation();
GetMachineDetails(CompleteInformation);
private void GetPersonalDetails(UserInformation CompleteInformation)
{
// you cannot make the CompleteInformation outside to point to new instance
}
C#代码被转换为C:
UserInformation *CompleteInformation = new UserInformation();
GetPersonalDetails(CompleteInformation);
void GetPersonalDetails(UserInformation *CompleteInformation)
{
// you cannot make the CompleteInformation outside to point to new instance
}
嗯... :-)仍在思考如何在整个C#术语中解释我的答案,而不是与C.思考......
答案 3 :(得分:0)
与C ++不同,在C#中将引用变量传递给函数意味着使用相同的变量。这意味着,您可以更改变量,并且此更改对调用者可见。 ref关键字允许更改引用本身(这意味着引用通过引用传递)。这意味着,函数可以将引用设置为null或将其分配给另一个对象,并且此更改对调用者可见。是的,ref应该由函数和调用者使用。这比在C ++中更好,你可以在调用者代码中看到,该参数是通过引用传递的。
如果您了解C / C ++,则将引用类型传递给不带ref关键字的函数与C ++中的*相同。使用ref将引用类型传递给函数与C ++中的**相同。