C# 返回值或输出参数哪个更好?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/810797/
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-05 02:06:36  来源:igfitidea点击:

Which is better, return value or out parameter?

c#reference

提问by Quan Mai

If we want to get a value from a method, we can use either return value, like this:

如果我们想从方法中获取一个值,我们可以使用任一返回值,如下所示:

public int GetValue(); 

or:

或者:

public void GetValue(out int x);

I don't really understand the differences between them, and so, don't know which is better. Can you explain me this?

我不太了解它们之间的区别,因此,不知道哪个更好。你能给我解释一下吗?

Thank you.

谢谢你。

采纳答案by Jon Skeet

Return values are almost alwaysthe right choice when the method doesn't have anything else to return. (In fact, I can't think of any cases where I'd everwant a void method with an outparameter, if I had the choice. C# 7's Deconstructmethods for language-supported deconstruction acts as a very, very rare exception to this rule.)

当该方法没有其他任何返回值时,返回值几乎总是正确的选择。(事实上,我不能想到这里我想任何情况下,曾经想要一个空白方法与out参数,如果我当初的选择。C#7的Deconstruct方法语言支持的解构作为一个非常,非常罕见的例外.)

Aside from anything else, it stops the caller from having to declare the variable separately:

除了其他任何事情外,它使调用者不必单独声明变量:

int foo;
GetValue(out foo);

vs

对比

int foo = GetValue();

Out values also prevent method chaining like this:

Out 值还可以防止方法链接,如下所示:

Console.WriteLine(GetValue().ToString("g"));

(Indeed, that's one of the problems with property setters as well, and it's why the builder pattern uses methods which return the builder, e.g. myStringBuilder.Append(xxx).Append(yyy).)

(确实,这也是属性设置器的问题之一,这就是构建器模式使用返回构建器的方法的原因,例如myStringBuilder.Append(xxx).Append(yyy)。)

Additionally, out parameters are slightly harder to use with reflection and usually make testing harder too. (More effort is usually put into making it easy to mock return values than out parameters). Basically there's nothing I can think of that they make easier...

此外,输出参数与反射一起使用稍微困难一些,并且通常也会使测试更加困难。(通常会付出更多的努力来使模拟返回值比输出参数更容易)。基本上没有什么我能想到的,它们让我变得更容易......

Return values FTW.

返回值 FTW。

EDIT: In terms of what's going on...

编辑:就发生了什么而言......

Basically when you pass in an argument for an "out" parameter, you haveto pass in a variable. (Array elements are classified as variables too.) The method you call doesn't have a "new" variable on its stack for the parameter - it uses your variable for storage. Any changes in the variable are immediately visible. Here's an example showing the difference:

基本上,当您为“out”参数传入一个参数时,您必须传入一个变量。(数组元素也被归类为变量。)您调用的方法在其堆栈上没有用于参数的“新”变量 - 它使用您的变量进行存储。变量中的任何更改都立即可见。这是一个显示差异的示例:

using System;

class Test
{
    static int value;

    static void ShowValue(string description)
    {
        Console.WriteLine(description + value);
    }

    static void Main()
    {
        Console.WriteLine("Return value test...");
        value = 5;
        value = ReturnValue();
        ShowValue("Value after ReturnValue(): ");

        value = 5;
        Console.WriteLine("Out parameter test...");
        OutParameter(out value);
        ShowValue("Value after OutParameter(): ");
    }

    static int ReturnValue()
    {
        ShowValue("ReturnValue (pre): ");
        int tmp = 10;
        ShowValue("ReturnValue (post): ");
        return tmp;
    }

    static void OutParameter(out int tmp)
    {
        ShowValue("OutParameter (pre): ");
        tmp = 10;
        ShowValue("OutParameter (post): ");
    }
}

Results:

结果:

Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10

The difference is at the "post" step - i.e. after the local variable or parameter has been changed. In the ReturnValue test, this makes no difference to the static valuevariable. In the OutParameter test, the valuevariable is changed by the line tmp = 10;

不同之处在于“post”步骤——即在局部变量或参数被改变之后。在 ReturnValue 测试中,这与静态value变量没有区别。在 OutParameter 测试中,value变量由行更改tmp = 10;

回答by kenny

I would prefer the following instead of either of those in this simple example.

在这个简单的示例中,我更喜欢以下内容而不是其中任何一个。

public int Value
{
    get;
    private set;
}

But, they are all very much the same. Usually, one would only use 'out' if they need to pass multiple values back from the method. If you want to send a value in and out of the method, one would choose 'ref'. My method is best, if you are only returning a value, but if you want to pass a parameter and get a value back one would likely choose your first choice.

但是,它们都非常相似。通常,只有在需要从方法中传回多个值时才会使用“out”。如果您想在方法中传入和传出一个值,可以选择“ref”。我的方法是最好的,如果你只返回一个值,但如果你想传递一个参数并取回一个值,一个人可能会选择你的第一选择。

回答by Scott Cowan

It's preference mainly

主要是偏好

I prefer returns and if you have multiple returns you can wrap them in a Result DTO

我更喜欢退货,如果您有多个退货,您可以将它们包装在 Result DTO 中

public class Result{
  public Person Person {get;set;}
  public int Sum {get;set;}
}

回答by pyrocumulus

What's better, depends on your particular situation. Oneof the reasons outexists is to facilitate returning multiple values from one method call:

哪个更好,取决于您的具体情况。其中一个原因out存在是为了方便从一个方法调用返回多个值:

public int ReturnMultiple(int input, out int output1, out int output2)
{
    output1 = input + 1;
    output2 = input + 2;

    return input;
}

So one is not by definition better than the other. But usually you'd want to use a simple return, unless you have the above situation for example.

因此,根据定义,一个并不比另一个更好。但通常你会想要使用简单的返回,除非你有上面的情况。

EDIT:This is a sample demonstrating one of the reasons that the keyword exists. The above is in no way to be considered a best practise.

编辑:这是一个示例,展示了关键字存在的原因之一。以上绝不是最佳实践。

回答by Brian

You should almost always use a return value. 'out' parameters create a bit of friction to a lot of APIs, compositionality, etc.

您几乎应该总是使用返回值。' out' 参数对许多 API、组合性等造成了一些摩擦。

The most noteworthy exception that springs to mind is when you want to return multiple values (.Net Framework doesn't have tuples until 4.0), such as with the TryParsepattern.

想到的最值得注意的例外是当您想要返回多个值时(.Net Framework 直到 4.0 才具有元组),例如TryParse模式。

回答by Martin Peck

You should generally prefer a return value over an out param. Out params are a necessary evil if you find yourself writing code that needs to do 2 things. A good example of this is the Try pattern (such as Int32.TryParse).

您通常应该更喜欢返回值而不是 out 参数。如果您发现自己编写的代码需要做两件事,那么 out params 是一种必要的邪恶。一个很好的例子是 Try 模式(例如 Int32.TryParse)。

Let's consider what the caller of your two methods would have to do. For the first example I can write this...

让我们考虑一下您的两种方法的调用者必须做什么。对于第一个例子,我可以写这个......

int foo = GetValue();

Notice that I can declare a variable and assign it via your method in one line. FOr the 2nd example it looks like this...

请注意,我可以在一行中声明一个变量并通过您的方法分配它。对于第二个例子,它看起来像这样......

int foo;
GetValue(out foo);

I'm now forced to declare my variable up front and write my code over two lines.

我现在被迫预先声明我的变量并将我的代码写成两行。

update

更新

A good place to look when asking these types of question is the .NET Framework Design Guidelines. If you have the book version then you can see the annotations by Anders Hejlsberg and others on this subject (page 184-185) but the online version is here...

在询问这些类型的问题时,一个不错的地方是 .NET Framework 设计指南。如果您有书籍版本,那么您可以看到 Anders Hejlsberg 和其他人对这个主题的注释(第 184-185 页),但在线版本在这里...

http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

If you find yourself needing to return two things from an API then wrapping them up in a struct/class would be better than an out param.

如果您发现自己需要从 API 返回两件事,那么将它们包装在结构/类中会比输出参数更好。

回答by danish

Both of them have a different purpose and are not treated the same by the compiler. If your method needs to return a value, then you must use return. Out is used where your method needs to return multiple values.

它们都具有不同的目的,并且编译器不会对其进行相同的处理。如果您的方法需要返回一个值,那么您必须使用 return。Out 用于您的方法需要返回多个值的地方。

If you use return, then the data is first written to the methods stack and then in the calling method's. While in case of out, it is directly written to the calling methods stack. Not sure if there are any more differences.

如果使用 return,则数据首先写入方法堆栈,然后写入调用方法的堆栈。而在out的情况下,则直接写入调用方法堆栈。不确定是否还有其他差异。

回答by Robin Day

You can only have one return value whereas you can have multiple out parameters.

您只能有一个返回值,而您可以有多个输出参数。

You only need to consider out parameters in those cases.

在这些情况下,您只需要考虑 out 参数。

However, if you need to return more than one parameter from your method, you probably want to look at what you're returning from an OO approach and consider if you're better off return an object or a struct with these parameters. Therefore you're back to a return value again.

但是,如果您需要从您的方法中返回多个参数,您可能需要查看您从 OO 方法返回的内容,并考虑是否最好返回带有这些参数的对象或结构体。因此,您又回到了返回值。

回答by user88637

There is no real difference. Out parameters are in C# to allow method return more then one value, that's all.

没有真正的区别。Out 参数在 C# 中允许方法返回多个值,仅此而已。

However There are some slight differences , but non of them are really important:

但是有一些细微的差异,但没有一个是真正重要的:

Using out parameter will enforce you to use two lines like:

使用 out 参数将强制您使用两行,例如:

int n;
GetValue(n);

while using return value will let you do it in one line:

而使用返回值会让你在一行中完成:

int n = GetValue();

Another difference (correct only for value types and only if C# doesn't inline the function) is that using return value will necessarily make a copy of the value when the function return, while using OUT parameter will not necessarily do so.

另一个区别(仅适用于值类型且仅当 C# 不内联函数时)是,使用返回值必然会在函数返回时复制该值,而使用 OUT 参数则不一定这样做。

回答by Andrew Webb

As others have said: return value, not out param.

正如其他人所说:返回值,而不是 out param。

May I recommend to you the book "Framework Design Guidelines" (2nd ed)? Pages 184-185 cover the reasons for avoiding out params. The whole book will steer you in the right direction on all sorts of .NET coding issues.

我可以向您推荐《框架设计指南》(第 2 版)这本书吗?第 184-185 页介绍了避免使用 out 参数的原因。整本书将引导您在各种 .NET 编码问题上朝着正确的方向前进。

Allied with Framework Design Guidelines is the use of the static analysis tool, FxCop. You'll find this on Microsoft's sites as a free download. Run this on your compiled code and see what it says. If it complains about hundreds and hundreds of things... don't panic! Look calmly and carefully at what it says about each and every case. Don't rush to fix things ASAP. Learn from what it is telling you. You will be put on the road to mastery.

与框架设计指南相结合的是静态分析工具 FxCop 的使用。您可以在 Microsoft 的网站上免费下载该软件。在编译后的代码上运行它,看看它说了什么。如果它抱怨成百上千的事情......不要惊慌!冷静而仔细地查看它对每个案例的描述。不要急于尽快解决问题。从它告诉你的东西中学习。您将走上精通之路。