假设一个名为“Place”的类存储位置和相关细节:
class Place
{
string Name;
string Location;
// etc...
}
稍后我们将填写多达80个不同城镇的名称和详细信息。所以我们将这些城镇以数字形式存储在一个数组中:
class Setup
{
public static GetTowns
{
for (int i = 1; i <= numberOfTowns; i++)
{
Town[i] = new Place(name, location);
}
// more code...
}
// more methods...
}
要访问特定城镇及其数据,我们将城镇本身作为参数传递并接收:
public static void DescribeTown(Place Town)
{
// example method from some other class
Console.WriteLine("Shipping to {0}.", Town.Name);
}
其他方法需要访问多个城镇或所有城镇。然后我们可以将整个Town数组作为参数传递:
public static void ListAllTowns(Place[] Town)
{
Console.WriteLine("Our Beloved Clients:");
foreach (Place here in Town)
{
Console.WriteLine("{0} in {1}", here.Name, here.Location);
// Various other operations requiring info about the Towns
}
}
完整参考,C#2.0,陈述以下内容
参数是接收调用时传递给方法的参数值的变量。
这似乎说每个类的每个实例,以及所涉及的所有数据,每次被调用时都会被传递到ListAllTowns
。这对我来说听起来很浪费,但不是吗?
(出于概念验证的原因,此示例严重简化,但方法需要读/写权限以及多个城镇之间的比较。)
答案 0 :(得分:7)
没有什么可以浪费的。你没有传递所有项目的副本,你只是创建一个数组,然后将对该数组的引用传递给ListAllTowns
方法(数组是引用类型)。
你正在以正确的方式做事(其中之一)。
答案 1 :(得分:4)
参数始终按值传递(除非使用ref
或out
关键字),但对于引用类型,值不是对象本身,而是对象的引用。
因此,整个对象不作为参数传递,只传递给对象。
答案 2 :(得分:2)
默认情况下,C#中的所有类都是引用,因此只有一个指针被发送到函数。
回答你的问题:这取决于你。有时将整个对象作为参数发送是有意义的(即我们正在尝试使用对象)。另一方面,仅为函数参数创建类可能并不好。在您的特定示例中,创建类是有意义的。
我刚才所说的一个例外:结构作为副本发送(所有成员都将被复制)。将这些作为函数参数发送时必须小心。
答案 3 :(得分:1)
在.NET中,对象作为引用保留。在这种情况下,您不会传递或复制整个数据,而是引用已创建的数据实例。
在这种情况下,鼓励传递整个实例,因为它允许你保持一致性(有意义的是,一个处理Towns的方法将Towns作为参数)
答案 4 :(得分:1)
这总是一个两难的问题。
一方面 - 奥卡姆的剃刀说你不需要任何过多的东西 - 在DescribeTown(Place Town)
改为DescribeTown(string TownName)
意味着不是以OOP方式进行,反过来意味着这就是代码将来很难改变和维持。
但有时当系统成熟且稳定且事实证明整个Town
仍然过多时,您可以将其重构为DescribeTown(string TownName)
。
还有一个方面 - 单元测试。比DescribeTown(string TownName)
更容易测试DescribeTown(Place Town)
方法,后者需要模拟Town对象,而且你应该模拟哪些属性并不明显(在测试之前你必须知道它)。
答案 5 :(得分:0)
我的观点是,将一个类作为参数传递是完全正确的。这是由罗伯特马丁斯清洁代码等各种作者提供支持。我也相信你应该尽可能避免传递参数。如果不是将一个Town对象数组传递给ListAllTowns方法,而是将“ListAll”作为Place类的方法,那么你可以调用这样的方法:
Towns.ListAll()
从这个意义上说,每次使用它时都不必将列表传递给函数,因为它只是在它自己的对象上运行。