1

以下 2 条建议中修改对象属性的最佳方法是什么,该对象正在由接受对象作为参数的类修改?

  1. 让类处理对象并返回一个值,然后将其分配给对象

或者。

  1. 使用 ref 关键字传递对象并让类修改对象而不实际返回任何内容。

例如,我有一个 Person 对象,其中包含 First Name 和 Last Name 以及 2 种不同的创建全名的方法。

哪个是最好的方法?

public static void Main()
{
    Person a = new Person {  FirstName = "John", LastName = "Smith" };
    Person b = new Person { FirstName = "John", LastName = "Smith" };

    NameProcesser np = new NameProcesser();

    // Example A
    a.FullName = np.CreateFullNameA(a);

    // Example B
    np.CreateFullNameB(ref b);
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }
}


public class NameProcesser
{
    public string CreateFullNameA(Person person)
    {
        return person.FirstName + " " + person.LastName;
    }

    public void CreateFullNameB(ref Person person)
    {
        person.FullName = person.FirstName + " " + person.LastName;
    }
}
4

4 回答 4

2

你不需要ref。只需修改方法中的对象。

当引用类型作为参数传递时,它是“按引用”传递的,而不是按值传递的。因此,当您修改它时,您实际上是在修改原始对象。只有ref在传递值类型(例如int.

我用引号说“通过引用”,因为实际发生的是指向原始对象的内部“指针”正在按值传递。

于 2012-09-26T20:25:47.377 回答
1

第一件事

您提到的事实ref表明您缺少一个基本概念;也就是说,可以访问对象引用的代码根据定义可以访问实际对象。

唯一可以想到的使用ref参数的使用场景是,当您想将该引用设置为某个其他对象或null.

如果您不使用ref(甚至out就此而言,请参阅此处的区别),您实际上是按值传递参数,这意味着创建了它的副本。

这意味着两件事,取决于参数是值类型(如 int、long、float 等)还是引用类型(引用任何类的实例)。

如果参数是值类型,则会创建它的副本。然后,您的方法可以为所欲为,因为副本仅限于该方法的范围。

但是,如果参数是引用类型(如您Person所愿),则仅复制引用本身:底层对象是相同的。这就是最大的区别所在。但是请记住,您在方法中可用的引用仍然是原始引用的副本,这意味着您可以将其设置为null,将其设置为另一个对象,简而言之,对它做任何您喜欢的事情:一旦方法返回,该引用将消失,原始引用将保持不变。

话虽如此

正如其他人告诉你的那样,真的没有必要使用ref.

此外,只要您处理诸如连接名字和姓氏之类的琐碎情况,我就会让对象本身来做(就像 Slapout 所做的那样)。

如果出现这种需要,以后总有时间分离职责。

还要考虑为这样一个微不足道的任务设置一个单独的类也可能被认为是违反直觉的。说这是手头的代码:

var p = new Person() { FirstName = "John", LastName = "Smith"} ;

Console.WriteLine(p.FullName);

当我这样做时,我完全期望FullName在任何时候都返回一些有意义的东西(即“John Smith”)。

相反,使用您的两种方法,如果我忘记(并且我会)打电话会发生什么CreateFullName

如果您确实需要将给定的关注点移动到单独的类中,请将其隐藏在属性的get方法中。

这样,人们就不需要知道你写的类的基础,而且它仍然是可测试的。

于 2012-09-26T21:04:40.103 回答
0

两者都 - 而且你不需要'ref' - 只需使用:

public void CreateFullNameB(Person person) 
{ 
    person.FullName = person.FirstName + " " + person.LastName; 
} 
于 2012-09-26T20:24:59.607 回答
0

首先,将方法分离到另一个类的唯一原因是该方法是否具有数据库或网络访问等依赖项。否则,那个简单的方法应该是Person类的属性。

此外,将整个对象传递给方法的唯一原因是对象数据在该方法中被广泛使用。否则最好将 FirstName 和 LastName 作为参数传递并返回结果。

类不需要通过ref修饰符来修改其内容。ref 仅在方法想要分配参数并引用新实例时才需要。

在您描述的示例中,如果从两个选项中进行选择,则返回值会更好,因为它减少了耦合并将逻辑与数据表示分离。但是如果一个实体的属性很少可以更新,那么传递对象会更好。

于 2012-09-26T20:29:56.957 回答