无法使用ref关键字。非常新手的问题!

时间:2010-04-25 14:28:02

标签: c# ref

这是我的班级:

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?

4 个答案:

答案 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 ++中的**相同。