通过引用传递:哪个更具可读性/更正确?

时间:2011-03-11 06:02:51

标签: c# coding-style design-guidelines

我有以下课程:

public class Person
{
     public String Name { get; set; }
}

我有一个方法,它将PersonString作为参数:

public void ChangeName(Person p, String name)
{
     p.Name = name;
}

由于Person是通过引用传递的,因此它应该更改传递的实例的Name

但这种方法比上面的方法更具可读性吗?

public Person ChangeName(Person p, String name)
{
     p.Name = name;
     return p;
}

8 个答案:

答案 0 :(得分:12)

更具可读性吗?不,实际上你可能会对他们造成更大的伤害。

通过让它返回一个Person对象,它可能会让你相信,而不是修改Person参数,它实际上是基于p创建一个新的Person但具有不同的名称,有人可能错误地认为p永远不会改变

无论哪种方式,如果你有一个对类没有影响的方法,那么它应该是静态的。这有助于您确定它不会影响其课程。只有方法返回一个值,如果你需要它返回一个值。

所以这是我对这种方法的建议:

public static void ChangeName(Person p, String name)
{
    p.Name = name;
}

答案 1 :(得分:1)

两种方法都没有任何对错。取决于您的计划需要什么。

很少需要返回传递给方法的参数,因为用户总是可以只使用作为参数传递的变量。

但是,它为您提供了最终覆盖此实现的灵活性,或者将此实现传递给另一个接受具有类似签名的委托的函数。然后,您可以传入其他不返回相同Person对象的实现。

只有在你真正需要灵活性时才这样做。

答案 2 :(得分:1)

我建议您使用以下其中一项以获得最佳可读性:

public static void ChangeName(Person p, String name)
{
    p.Name = name;
}

public static Person WithName(Person p, String name)
{
    return new Person(p) { Name = name };    
}

第二个将Person对象视为不可变,并且不会更改对象的状态。 ChangeName函数显式更改输入对象的状态。我认为明确区分这两种方法很重要。一个好的经验法则是方法不应该改变对象的状态并同时返回一个。

答案 3 :(得分:1)

首先在第一个例子中没有通过引用传递p。你的第二种方法让人相信它会返回一个新的参考,而不是。所以我认为第二个比第一个更清晰。

答案 4 :(得分:0)

在你描述的情况下,我不会说。你用这种方法尝试做什么并不是很清楚。只需使用该对象并设置属性即可。将方法插入执行路径只会使理解复杂化并创建对Person对象及其基础值的另一依赖。

如果你问的是一个超出你发布的代码的某个设计的元问题,那么我就错过了它。

答案 5 :(得分:0)

第一个更好,因为第二个可能会让你相信p是不可变的。 但是,整个方法都没用,因为它只是调用setter。为什么不直接调用setter?

答案 6 :(得分:0)

我认为你的第二种方法更具可读性YAGNI。但如果你像这样改变它

public static class PersonExtensions 
{
public static Person ChangeName(this Person p, String name)
{
 p.Name = name;
 return p;
}

流畅的界面 a la

扩展方法
new Person().ChangeName("Peter Smith").SendEmail().Subject("Test Mail").Receiver("....)

答案 7 :(得分:0)

Here是理解通过值/引用传递参数的权威参考。

查看代码,为什么不使用属性?

public string Name
{
   set {name = value;}
   get { return name; }
}

编辑:Auto implemented properties

public string Name
{
   set;
   get;
}