我何时应该使用参数?

kay*_*one 50 .net c# out

我不明白何时应该使用输出参数,如果我需要返回多个类型,我个人将结果包装成新类型,我发现使用它比使用更容易.

我见过像这样的方法,

   public void Do(int arg1, int arg2, out int result)
Run Code Online (Sandbox Code Playgroud)

有没有真正有意义的案例?

怎么样TryParse,为什么不返回一个ParseResult类型?或者在较新的框架中返回一个null-able类型?

jas*_*onh 27

当你有一个TryNNN函数时,out很好,很明显即使函数没有成功,也会设置out参数.这允许您依赖于您声明的局部变量将被设置的事实,而不是必须在稍后的代码中对null进行检查.(下面的注释表明该参数可以设置为null,因此您可能需要验证您正在调用的函数的文档,以确定是否是这种情况.)它使代码更清晰,更容易读.另一种情况是,当您需要返回一些数据和方法条件的状态时,如:

public bool DoSomething(int arg1, out string result);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,返回可以指示函数是否成功,结果是否存储在out参数中.不可否认,这个例子是设计的,因为你可以设计一种方法,函数只返回一个string,但你明白了.

缺点是你必须声明一个局部变量来使用它们:

string result;
if (DoSomething(5, out result))
    UpdateWithResult(result);
Run Code Online (Sandbox Code Playgroud)

代替:

UpdateWithResult(DoSomething(5));
Run Code Online (Sandbox Code Playgroud)

然而,这甚至可能不是一个缺点,它取决于你想要的设计.在DateTime的情况下,提供了两种方法(Parse和TryParse).

  • 现在您不再需要声明局部变量:`if (DoSomething(5, out var result) { ... }`。 (5认同)
  • "如果函数不成功,out-parameter将不会被更改." - 除非函数抛出异常,否则将更改out参数wil**.如果具有out参数的方法具有不为out参数赋值的执行路径,则该方法将无法编译.因此初始化'string result ="";' 在你的第二个例子是不必要的. (4认同)

Gis*_*shu 6

这与大多数事情有关.让我们看一下选项

  • 你可以返回任何你想要的函数的返回值
  • 如果要返回多个值或函数已经有返回值,则可以使用params或创建一个新的复合类型,将所有这些值公开为属性

在TryParse的情况下,使用out参数是有效的 - 你不必创建一个新的类型,它将是16B的开销(在32b机器上)或者在调用后产生垃圾收集的性能.例如,可以在循环内调用TryParse - 所以这里的params规则.
对于不在循环中调用的函数(即性能不是主要问题),返回单个复合对象可能是"更清晰"(对于旁观者来说是主观的).现在使用匿名类型和动态类型,它可能变得更加容易.

注意:

  1. outparams有一些需要遵循的规则,即编译器将确保函数在退出之前初始化值.因此,即使解析操作失败,TryParse也必须将out参数设置为某个值
  2. TryXXX模式是何时使用params的一个很好的例子 - Int32.TryParse被引入了coz人们抱怨捕获异常以确定解析是否失败.在解析成功的情况下,你最有可能做的就是获得解析后的值 - 使用out参数意味着你不必再对Parse进行另一个方法调用


dev*_*xer 6

我认为 out 在需要返回布尔值和值的情况下很有用,例如 TryParse,但如果编译器允许这样的事情,那就太好了:

bool isValid = int.TryParse("100", out int result = 0);
Run Code Online (Sandbox Code Playgroud)

  • 这现在在 C# 7 中可用 (10认同)

小智 5

我知道答案晚了几年。如果您不希望您的方法实例化一个新对象以返回,out(以及 ref)也非常有用。这在您希望为您的方法实现亚微秒性能的高性能系统中非常重要。从内存访问的角度来看,实例化是相对昂贵的。