C# 修改方法内的方法参数或返回结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/555471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:01:00  来源:igfitidea点击:

Modify method parameter within method or return result

c#.net

提问by JMS

What is the difference between

之间有什么区别

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

and

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

when used as either

当用作

DoSomething(value);

versus

相对

value = DoSomething(value);

采纳答案by Rex M

You are talking about the difference between passing by referenceand passing by value, which is conceptually similar to the idea of value types vs reference types.

您正在谈论按引用传递按值传递之间的区别,这在概念上类似于值类型与引用类型的想法。

If you pass a value typeinto the method, you have to use the second example; otherwise you are just incrementing an integer that exists inside the scope of DoSomething(). Try it: if you execute your first example, after DoSomething() has run, the value of your int will be unchanged.

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

However, if you are passing in something other than a value type (say object foo), you are actually passing a referenceto the original object. Anything you do to it inside DoSomething() will take effect outside the method as well, since you are still referring to the same object.

但是,如果您传入的不是值类型(例如对象 foo),则实际上是在传递对原始对象的引用。您在 DoSomething() 内对其执行的任何操作也将在方法外生效,因为您仍然引用同一个对象。

You can accomplish what you're attempting in the first example by writing:

您可以通过编写以下代码来完成您在第一个示例中尝试的操作:

void DoSomething(ref int value)

That instructs .NET to pass a reference to the item regardless of whether it is a value type.

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

See this writeup on Value Types vs Reference Typeson MSDN for a more detailed look.

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

Additionally, as zodoz points out(upvote appropriately), by returning value++you are returning and then incrementing. To return the incremented value, use ++value.

此外,正如zodoz 指出的(适当地投票),通过返回,value++您将返回然后递增。要返回增加的值,请使用++value

回答by iopener

With most programming languages, you would need to change up your void function by passing the parameter by reference. A function usually can't change the value of its parameters; instead, it creates a copy of the parameter and works with that instead.

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

In order to work with the actual variable, you have to change the function header to accept a reference to the variable, with a preceding ampersand (&) like this:

为了使用实际变量,您必须更改函数头以接受对该变量的引用,并在前面加上一个与号 (&),如下所示:

private void DoSomething(int &value)

Hope that helps!

希望有帮助!

回答by CMS

In your first example, the int parameter valueis incremented, but is destroyed when the method ends, you cannot get the value outside the method, unless you use the refor outkeywords.

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

For example:

例如:

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

// ...
int myValue = 5;
DoSomething(ref myValue);
// Now myValue is 6.

Ref and out parameter passing modes are used to allow a method to alter variables passed in by the method caller. The main difference between ref and out may be subtle but it's important.

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

Each parameter passing mode is designed to suite different programming needs.

每种参数传递模式旨在适应不同的编程需求。

The caller of a method which takes an outparameter is not required to assign to the variable passed as the out parameter prior to the call; however, the method is requiredto assign to the out parameter before returning.

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

One way to think of out parameters is that they are like additional return values of a method. They are convenient when a method should return more than one value.

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

The refparameters causes the arguments to be passed by reference. The effect is that any changes to the parameter in the method will be reflected in that variable when control passes back to the calling method.

REF参数使参数通过引用传递。结果是,当控制权返回给调用方法时,对方法中参数的任何更改都将反映在该变量中。

Do not confuse the concept of passing by reference with the concept of reference types.

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

The two concepts are not related; a method parameter can be modified by ref regardless of whether it is a value type or a reference type, there is no boxing of a value type when it is passed by reference.

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

回答by Ray

Simply the first one won't work because you're operating on a copy of value.

只是第一个不起作用,因为您正在操作价值的副本。

You could do something like

你可以做类似的事情

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

and call it like

并称之为

DoSomething(ref value);

This changes value to be passed in by reference. But really the only reason to do this is if you want to return more than one thing from your function. And normally there are better ways.

这会更改要通过引用传入的值。但真正这样做的唯一原因是,如果您想从函数中返回不止一件事。通常有更好的方法。

For extra bonus knowledge, there's also the out keyword which is similar to ref, but doesn't require value to be initialised first.

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

回答by James Matta

Since you are using postfix ++ the value returned is the original value of the number. Additionally since you are passing a copy of the number and not the number itself (ie by reference) the changes made to value don't affect the variable you passed.

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

So a program like this:

所以一个这样的程序:

int value=1;
std::cout<<value<<std::endl;
value = DoSomething(value);
std::cout<<value<<std::endl;

DoSomething(value);
std::cout<<value<<std::endl;

Should output as follows:

应该输出如下:

1
1
1

If you were to use prefix ++ in the returning or if you were to pass by reference in the non-returning function the same program would output as follows.

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

1
2
3

Hope that this helps.

希望这会有所帮助。

回答by Mike

Everyone else seems to be suggesting the difference in variable passing, but I noticed something different:

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

If the example code you are displaying is a simplification of something you are already looking at, then you might want to note that in your second example:

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

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

The valuewill return thenincrement. So if you do the following:

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

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

Your output will be 1.

您的输出将是1.

Let me know if this helps at all.

让我知道这是否有帮助。

回答by Wedge

Return a value.

返回一个值。

Why?

为什么?

Correctness, Readability, and Self-Documentation

正确性、可读性和自我记录

Intentional and easy to understand code is better than side-effect code. Consider:

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

float area = pi * Square(r);

vs.

对比

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

Also consider the advantages of terseness through composability in the first example.

还要考虑第一个示例中通过可组合性带来的简洁性优势。

Consider the methods themselves, compare:

考虑方法本身,比较:

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

Which is pretty obviously correct. vs.

这显然是正确的。对比

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

Which seems right and will compile just fine but is actually just a no-op. What you really want is this:

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

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

// client code:
DoSomething(ref a);

Variables are Cheap

变量便宜

Many well-named variables is preferable over few reused general purpose variables. Resist the temptation to prematurely optimize, the chance that you will need to cut down on the number of local variables to improve the performance of your system is cosmically tiny. Again, Variables are Cheap, DON'T REUSE VARIABLES!

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

Testability

可测试性

Consider:

考虑:

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

vs.

对比

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

There are many other advantages to avoiding mutation in preference to returning a value. It's not merely an accident that mathematics defines a function as a mapping of input values to output values.

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