.net 在方法或返回结果中修改方法参数

0vvn1miw  于 2023-11-20  发布在  .NET
关注(0)|答案(6)|浏览(199)

有什么区别

  1. private void DoSomething(int value) {
  2. value++;
  3. }

字符串

  1. private int DoSomething(int value) {
  2. return value++;
  3. }


当用作

  1. DoSomething(value);


  1. value = DoSomething(value);

t40tm48m

t40tm48m1#

你在谈论通过引用传递通过值传递之间的区别,这在概念上类似于值类型与引用类型的想法。
如果你传递一个值类型到方法中,你必须使用第二个例子;否则你只是递增一个存在于DoSomething()范围内的整数。试试看:如果你执行第一个例子,在DoSomething()运行之后,你的int的值将保持不变。
然而,如果你传入的不是值类型(比如对象foo),你实际上是在传递一个对原始对象的引用。你在DoSomething()中对它所做的任何事情都将在方法外部生效,因为你仍然引用同一个对象。
您可以通过编写以下代码来完成第一个示例中的尝试:

  1. void DoSomething(ref int value)

字符串
它指示.NET传递对该项的引用,而不管该项是否为值类型。
有关详细信息,请参阅MSDN上**Value Types vs Reference Types**上的这篇文章。
此外,正如zodoz指出的(适当地提高),通过返回value++,您正在返回然后递增。要返回递增的值,请使用++value

nsc4cvqm

nsc4cvqm2#

返回值。

为什么?为什么?

正确性、可读性和自我文档化

有意识的、易于理解的代码比有副作用的代码更好。

  1. float area = pi * Square(r);

字符串
vs.

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


还要考虑第一个示例中通过可组合性实现简洁的优点。
考虑方法本身,比较:

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


这显然是正确的。

  1. void DoSomething(int value)
  2. { value++; }


这看起来是正确的,可以很好地编译,但实际上只是一个空操作。你真正想要的是:

  1. void DoSomething(ref int value)
  2. { value++; }
  3. // client code:
  4. DoSomething(ref a);

变量很便宜

许多命名良好的变量比很少重用的通用变量更可取。抵制过早优化的诱惑,你需要减少局部变量的数量来提高系统性能的机会是非常小的。再次强调,变量很便宜,不要重用变量!

可测试性

请考虑:

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


vs.

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


避免变异而不是返回值还有很多其他的好处,数学将函数定义为输入值到输出值的Map不仅仅是一个偶然。

展开查看全部
xkrw2x1b

xkrw2x1b3#

其他人似乎都在暗示变量传递的不同,但我注意到了一些不同的东西:
如果您正在显示的示例代码是您已经看到的东西的简化,那么您可能需要在第二个示例中注意:

  1. private int DoSomething(int value) {
  2. return value++;
  3. }

字符串
value将返回thenincrement。因此,如果您执行以下操作:

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


您的输出将是1
如果有帮助就告诉我。

展开查看全部
llew8vvj

llew8vvj4#

简单地说,第一个是行不通的,因为你操作的是价值的副本。
你可以这样做

  1. private int DoSomething(ref int value)
  2. {
  3. value++;
  4. }

字符串
就像

  1. DoSomething(ref value);


这将改变通过引用传递的值。但实际上这样做的唯一原因是如果你想从函数中返回多个东西。通常有更好的方法。
对于额外的奖励知识,还有类似于ref的out关键字,但不需要首先初始化value。

展开查看全部
h4cxqtbf

h4cxqtbf5#

在第一个示例中,int参数value递增,但在方法结束时被销毁,您无法在方法外部获取值,除非使用refout关键字。
举例来说:

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

字符串
Ref和out参数传递模式用于允许方法修改由方法调用者传入的变量。ref和out之间的主要区别可能很微妙,但很重要。
每种参数传递模式都是为了满足不同的编程需求而设计的。
一个方法的调用者如果接受了一个out参数,则不需要在调用之前赋值给作为out参数传递的变量;但是,在返回之前,方法需要赋值给out参数。
我们可以把out参数看作是一个方法的附加返回值,当一个方法返回多个值时,使用out参数是很方便的。

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

  • 不要混淆引用传递的概念和引用类型的概念 *。

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

展开查看全部
ubby3x7f

ubby3x7f6#

在大多数编程语言中,你需要通过引用传递参数来改变你的void函数。一个函数通常不能改变它的参数值;相反,它创建一个参数的副本并使用它。
为了使用实际的变量,你必须修改函数头以接受对变量的引用,前面有一个&符号(&),如下所示:

  1. private void DoSomething(int &value)

字符串
希望有帮助!

相关问题