【问题标题】:Trouble using the ref keyword. Very newbie question!使用 ref 关键字时遇到问题。很新手的问题!
【发布时间】:2010-04-25 14:28:02
【问题描述】:

这是我的课:

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 吗?

【问题讨论】:

    标签: c# ref


    【解决方案1】:

    当您将引用类型(在您的情况下,您的 UserInformation 类是引用类型)作为参数传递时,默认情况下您将指针传递给类按值,这意味着GetPersonalDetails 将获得自己的指针副本,该指针指向UserInformation 类的相同 实例。

    在您的示例中使用 ref 关键字会将指向 UserInformationinstance 的相同指针传递给方法。

    因此,在您的情况下,如果您的意图是简单地修改 UserInformation 的属性,则不需要 ref 关键字,因为您将修改来自 GetPersonalDetailsGetMachineDetails 的实际实例。但是,如果您的意图是从这些方法中实例化一个新的 UserInformation 对象或将实例设置为 null,则需要使用 ref 关键字。

    Jon Skeet 很好地解释了this article 中的参数传递。

    【讨论】:

      【解决方案2】:

      您可能不需要在这里使用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";
          }
      

      【讨论】:

      • 对。唯一需要对类对象使用 ref 的情况是,如果你想说 foo = somethingElse。
      • 您能详细说明一下吗?你能在不使用 ref 的情况下向我展示我的代码,这样它就可以像我现在拥有的那样工作吗?我渴望学习!
      • @Sergio:你的代码没有做任何事情......你所说的“像我现在一样工作”是什么意思?
      • 我希望 GetMachine/GetPersonal 方法设置创建的“CompleteInformation”变量的属性。你确定我在这种情况下不需要使用 Ref 吗?
      • 尝试编写一个小测试项目来演示它,但是是的,这是正确的:您不需要使用 ref 来调用 getter 和 setter。
      【解决方案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 类比。思考..

      【讨论】:

        【解决方案4】:

        与 C++ 不同,在 C# 中将引用变量传递给函数意味着使用相同的变量。这意味着,您可以更改变量,并且此更改对调用者可见。 ref 关键字允许更改引用本身(这意味着,引用通过引用传递)。这意味着,函数可以将引用设置为 null 或将其分配给另一个对象,并且此更改对调用者可见。是的,函数和调用者都应该使用 ref。这比在 C++ 中要好,您可以在调用者代码中看到,该参数是通过引用传递的。

        如果您了解 C/C++,则将引用类型传递给不带 ref 关键字的函数与 C++ 中的 * 相同。使用 ref 将引用类型传递给函数与 C++ 中的 ** 相同。

        【讨论】:

          猜你喜欢
          • 2013-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-22
          • 2012-07-24
          • 1970-01-01
          相关资源
          最近更新 更多