修改方法或返回结果中的方法参数

有什么区别

private void DoSomething(int value) { value++; } 

 private int DoSomething(int value) { return value++; } 

当用作任何一种

 DoSomething(value); 

 value = DoSomething(value); 

您正在讨论通过引用 传递传递值之间的区别,这在概念上类似于值类型与引用类型的概念

如果将值类型传递给方法,则必须使用第二个示例; 否则你只是递增一个存在于DoSomething()范围内的整数。 试一试:如果执行第一个例子,在运行DoSomething()之后,int的值将保持不变。

但是,如果要传递的值不是值类型(比如对象foo),则实际上是在传递对原始对象的引用 。 你在DoSomething()中做的任何事情也会在方法之外生效,因为你仍然指的是同一个对象。

您可以通过编写以下内容来完成您在第一个示例中尝试的内容:

 void DoSomething(ref int value) 

这指示.NET传递对项的引用,而不管它是否为值类型。

有关详细信息,请参阅MSDN上的值类型与引用类型的此文章。

此外,正如zodoz指出的那样 (适当地提升 ),通过返回value++你将返回然后递增。 要返回递增的值,请使用++value

返回一个值。

为什么?

正确性,可读性和自我文档

有意且易于理解的代码优于副作用代码。 考虑:

 float area = pi * Square(r); 

 Square(r); float area = pi * r; // ... intervening code float x = r * 5; // did you mean to use the original r or r-squared here? 

在第一个例子中还要考虑通过可组合性的简洁性的优点。

考虑方法本身,比较:

 int DoSomething(int value) { return value+1; } 

这显然是正确的。 与

 void DoSomething(int value) { value++; } 

这似乎是正确的,并将编译得很好,但实际上只是一个无操作。 你真正想要的是这个:

 void DoSomething(ref int value) { value++; } // client code: DoSomething(ref a); 

变量很便宜

许多命名良好的变量优于少数重用的通用变量。 抵制过早优化的诱惑,您需要减少局部变量的数量以提高系统性能的可能性非常小。 再次,变量是便宜的,不要重复变量!

可测性

考虑:

 Assert.IsTrue(Square(2) == 4); 

 float a = 2; Square(a); Assert.IsTrue(a == 4); 

避免突变优先于返回值还有许多其他优点。 数学将函数定义为输入值到输出值的映射不仅仅是一个意外。

只是第一个不起作用,因为你在一个价值副本上运作。

你可以做点什么

 private int DoSomething(ref int value) { value++; } 

并称之为

 DoSomething(ref value); 

这会更改要通过引用传递的值。 但实际上,唯一的理由就是如果你想从函数中返回多个东西。 通常有更好的方法。

对于额外的奖励知识,还有out关键字与ref类似,但不需要首先初始化值。

其他人似乎都在暗示变量传递的差异,但我注意到了一些不同的东西:

如果您显示的示例代码是您正在查看的内容的简化,那么您可能需要在第二个示例中注意:

 private int DoSomething(int value) { return value++; } 

value将返回然后递增。 因此,如果您执行以下操作:

 public Main() { int val = 1; Console.writeln(DoSomething(val)); } 

你的输出将是1

如果这有帮助,请告诉我。

在第一个示例中,int参数value递增,但在方法结束时销毁,除非使用ref或out关键字,否则无法获取方法外的值。

例如:

 private int DoSomething(ref int value) { return value++; } // ... int myValue = 5; DoSomething(ref myValue); // Now myValue is 6. 

Ref和out参数传递模式用于允许方法更改方法调用者传入的变量。 ref和out之间的主要区别可能很微妙但很重要。

每个参数传递模式都旨在满足不同的编程需求。

取出参数的方法的调用者不需要分配给在调用之前作为out参数传递的变量; 但是,该方法需要在返回之前分配给out参数。

考虑参数的一种方法是它们就像方法的附加返回值。 当方法应返回多个值时,它们很方便。

ref参数导致参数通过引用传递。 结果是,当控制传递回调用方法时,方法中参数的任何更改都将反映在该变量中。

不要将引用传递的概念与引用类型的概念混淆

这两个概念没有关系; 方法参数可以通过ref修改,无论它是值类型还是引用类型,当通过引用传递时,没有值类型的装箱。

对于大多数编程语言,您需要通过引用传递参数来更改void函数。 函数通常不能改变其参数的值; 相反,它会创建参数的副本并改为使用它。

为了使用实际变量,您必须更改函数头以接受对变量的引用,并使用前面的&符号(&):

 private void DoSomething(int &value) 

希望有所帮助!

由于您使用的是postfix ++,因此返回的值是该数字的原始值。 此外,由于您传递的是数字的副本而不是数字本身(即通过引用),因此对值所做的更改不会影响您传递的变量。

所以像这样的程序:

 int value=1; std::cout< 

应输出如下:

 1 1 1 

如果您在返回时使用前缀++,或者如果您要在非返回函数中通过引用传递,则相同的程序将输出如下。

 1 2 3 

希望这会有所帮助。