当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《修改方法或返回结果中的方法参数》经验,为你挑选了4个好方法。

有什么区别

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

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

当用作任何一种

DoSomething(value);

value = DoSomething(value);

Rex M.. 49

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

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

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

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

void DoSomething(ref int value)

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

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

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



1> Rex M..:

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

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

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

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

void DoSomething(ref int value)

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

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

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


请记住,在'参数引用类型'的情况下,您正在做的是传递引用的*值*.它仍然是通过价值.添加ref使其真正通过引用传递(因此,不是传递值的副本,而是将'被调用的函数指向实际值).

2> Wedge..:

返回一个值.

为什么?

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

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

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);

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



3> Mike..:

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

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

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

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

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

你的输出将是1.

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



4> Ray..:

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

你可以做点什么

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

并称之为

DoSomething(ref value);

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

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

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有