参考值参数 VS 返回值,哪个更好?

4

当我们想要修改一个对象中的某个值时,可以使用两种不同的方法,想知道哪种方法更好或它们之间没有太大的区别。

    1.
  

void SomeMethod()
   {
      UserInfo newUser = New UserInfo();
      ModifyUserInfo(newUser);
      //Modify UserInfo after calling void method GetUserInfo
   }




           void ModifyUserInfo(UseerInfo userInfo)
           {
               userInfo.UserName = "User Name";
               .....
           }
    2.
  
    void SomeMethod()
       {
          UserInfo newUser = New UserInfo();
          //Assign new userinfo explicitly
          newUser = GetUserInfo(newUser);

       }


       UserInfo ModifyUserInfo(UseerInfo userInfo)
       {
           userInfo.UserName = "User Name";
           .....
           return userInfo;
       }

无法在此网站的格式中回答这个问题。阅读 Uncle Bob 的《Clean Code》一书以获得答案。 - Mark Seemann
2
你的第二个片段给人的印象是它创建了一个新对象。实际上它并没有,不要使用它。 - Hans Passant
6个回答

5

我更倾向于第三个选项:

   void SomeMethod()
   {
      UserInfo newUser = GetUserInfo();
   }


   UserInfo GetUserInfo()
   {
       UserInfo userInfo = New UserInfo();
       userInfo.UserName = "User Name";
       .....
       return userInfo;
   }

基本上,这让 GetUserInfo 处理构建 UserInfo 的所有细节,而您的调用代码不必担心除了获取对象之外的任何细节。


嗯,如果这个方法接受一个已经存在的 UserInfo 对象,并填充电子邮件、公司、传真等信息,同时保留其他字段不变,那会怎么样呢? - Andras Vass
如果选择这条路,为什么不让一个UserInfo构造函数来处理它呢?哦,我同意Andras的观点。ModifyUserInfo比一次性构建UserInfo有更多的用途。 - Bob
好的观点;我一直在努力让我的代码与他的保持接近。但是(仍然)更好的实现可能是通过一个构造函数来初始化所有内容,并提供属性或Modify()方法来处理对现有对象的更新,作为一个类来完成。 - Justin Ethier
Andras的想法和我的一样。我只是想比较明确返回对象和通过引用对象隐式返回的优缺点。在我的当前项目中,我们使用第一种方法处理从数据读取器到对象(实体)的所有转换。 - CodeYun
Justin:理解了你的观点,但是你假设OP对UserInfo有控制权。那么让我们看看在这种情况下如何扩展UserInfo:假设你在3.5中 - 另一个假设 - 并创建了一个扩展方法。那么该方法的签名会是什么?难道不应该是static void ModifyUserInfo(this UserInfo userinfo, string username)吗? :) 此外,OP可能希望分离操作并放弃扩展方法。这有很多合法的原因。(WCF,管理器模式等) - Andras Vass

3

从第二个签名 - UserInfo ModifyUserInfo(UseerInfo userInfo) - 我可能会认为它会将 UserInfo 视为 不可变的

我可能会被误导认为它会 复制 传入的对象,并返回一个修改后的新对象


0

轻率的回答:它们都不好。这是:

UserInfo newUser = New UserInfo(); 
newUser.Modify();

或者,如果UserInfo更适合建模为值对象

UserInfo newUser = New UserInfo();
var u = newUser.Modify();

虽然在后一种情况下,我可能会给这个方法取一个不同的名字。


0

第一种方法是可以的。这不是引用参数,通过引用传递是:ref UserInfo userInfo,并且不建议使用。FxCop规则之一是:不要通过引用传递类型,但这不是你所做的。


0

你甚至可以拥有

UserInfo ui = new UserInfo {UserName = "User Name", ...}

(在C# 3.0中)。但总的来说,如果这是一个引用类型,请不要每次都实例化它,除非真的需要(比如System.String)-我说的是第二个示例。

0
第一种方法。第二种方法没有任何意义;如果不检查代码(或文档),就无法知道它是否返回传入的UserInfo实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接