提问人:BrightonDev 提问时间:9/27/2012 最后编辑:one noaBrightonDev 更新时间:11/15/2023 访问量:821
修改作为参数传递到修改类中的对象的正确方法
The correct way to modify an object that is being passed as a parameter into the modifying class
问:
以下 2 条建议中,修改由接受该对象作为参数的类修改的对象上的属性的最佳方法是什么?
- 让类对对象进行处理,并返回一个值,然后将该值分配给该对象
或。
- 使用 ref 关键字传递对象,并让类在不实际返回任何内容的情况下修改对象。
例如,我有一个 Person 对象,其中包含“名字”和“姓氏”以及 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;
}
}
答:
两者都不需要 - 你也不需要 'ref' - 只需使用:
public void CreateFullNameB(Person person)
{
person.FullName = person.FirstName + " " + person.LastName;
}
你不需要 .只需修改方法中的对象即可。ref
当引用类型作为参数传递时,它是“按引用”传递的,而不是按值传递的。因此,当你修改它时,你实际上是在修改原始对象。仅当传递值类型(如 .ref
int
我在引号中说“通过引用”,因为实际发生的事情是指向原始对象的内部“指针”正在通过值传递。
评论
首先,将该方法分成其他类的唯一原因是该方法是否具有数据库或网络访问等依赖项。否则,这个简单的方法应该是类的属性。Person
此外,将整个对象传递给方法的唯一原因是当对象数据在该方法中被广泛使用时。否则,最好将 FirstName 和 LastName 作为参数传递并返回结果。
类不需要使用 modifier 传递来修改其内容。仅当方法想要将参数与对新实例的引用一起分配时,才需要 ref。ref
在示例中,您描述了如果从两个选项中进行选择,则返回值会更好,因为它可以减少耦合并将逻辑与数据表示分开。但是,如果一个实体的属性很少可以更新,那么传递对象会更好。
评论
Person
第一件事
你提到的事实表明你错过了一个基本概念;也就是说,根据定义,可以访问对对象的引用的代码可以访问实际对象。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
相反,使用您的这两种方法,如果我忘记(并且我会)打电话会发生什么?CreateFullName
如果您确实需要将给定的关注点移动到单独的类中,请将其隐藏在属性的方法中。get
这样一来,人们就不需要知道你编写的类的基础,而且它仍然是可测试的。
评论
上一个:在方法中修改方法参数或返回结果
评论