我有以下课程:
public class Person
{
public String Name { get; set; }
}
我有一个方法,它将Person
和String
作为参数:
public void ChangeName(Person p, String name)
{
p.Name = name;
}
由于Person
是通过引用传递的,因此它应该更改传递的实例的Name
。
但这种方法比上面的方法更具可读性吗?
public Person ChangeName(Person p, String name)
{
p.Name = name;
return p;
}
答案 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;
}