在c#中ref和out参数之间哪个更轻?

时间:2021-01-17 21:03:42

Can anyone tell me which one is lighter between ref and out. I know the exact difference between ref and out keyword and usage as well.

谁能告诉我在裁判和出局之间哪个更轻?我知道ref和out关键字以及用法之间的确切区别。

In my case I can use both ref and out, but wondering the lighter one.

在我的例子中,我可以同时使用ref和out,但是我想知道更轻的那个。

If some one needs to refer please go here and let me know the lighter ones.

如果有人需要参考,请到这里来,告诉我轻一点的。

Thanks in advance..

提前谢谢. .

4 个解决方案

#1


12  

The only difference is a compiler hint.

唯一的区别是编译器提示。

... out ...

…出……

public static void TestOut(out int test)
{
    test = 1;
}

.method public hidebysig static void  TestOut([out] int32& test) cil managed
{
  // Code size       4 (0x4)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stind.i4
  IL_0003:  ret
} // end of method Program::TestOut

... ref ...

…裁判…

public static void TestRef(ref int test)
{
    test = 1;
}

.method public hidebysig static void  TestRef(int32& test) cil managed
{
  // Code size       4 (0x4)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stind.i4
  IL_0003:  ret
} // end of method Program::TestRef

... out and ref are effectively the same. The only real difference being that out tells the compiler to expect the value to be set before the method is returned. You could send a value to a function that has an out flag but again the compiler will treat it as an unassigned variable. The runtime doesn't really care. Both will be created as a pointer to the variable. You are best to use the keyword that describes the functionality you expect with your function. Any optimization that "may" take place in the JITer below this will have near 0 impact on the application.

…out和ref实际上是一样的。唯一的区别是,out告诉编译器在返回方法之前要设置值。你可以将一个值发送给一个带有out标志的函数,但是编译器会把它当作一个未赋值的变量。运行时并不关心。两者都将被创建为一个指向变量的指针。您最好使用关键字来描述您期望的函数的功能。任何“可能”在下面的抖动中发生的优化都会对应用程序产生接近0的影响。

#2


3  

They will most likely be the same at the low-level. If there is a performance difference, it's probably negligible and there are better places to optimize.

在低层次上,它们很可能是相同的。如果存在性能差异,那么它可能是可以忽略的,并且有更好的地方可以优化。

#3


3  

This is a micro-optimization.

这是一个优化上。

Actually, if you have a look at the IL code that is being generated for both options, you'll see no difference. Except for the compiler hint that Matthew Whited indicated:

实际上,如果您看一下为两个选项生成的IL代码,您会发现没有区别。除了马修暗示的编译器:

.method private hidebysig static void  Out([out] valuetype [mscorlib]System.DateTime& d) cil managed

.method private hidebysig static void  Ref(valuetype [mscorlib]System.DateTime& d) cil managed

I'd just suggest the option that is semantically the most correct one for the situation at hand.

我只是建议选择在语义上最适合当前情况的选项。

#4


2  

See this link In particular the section, "Conclusion 4:":

请看这一链接,特别是“结论4:”一节:

"out" and "ref" are actually exactly the same behind the scenes. The CLR only supports "ref"; "out" is just "ref" where the compiler enforces slightly different rules regarding when the variable in question is known to have been definitely assigned. That's why it is illegal to make method overloads that differ solely in out/ref-ness; the CLR cannot tell them apart! Therefore the rules for type safety for out have to be the same as for ref.

“out”和“ref”实际上在幕后是完全相同的。CLR只支持“ref”;“out”仅仅是“ref”,编译器对所讨论的变量何时被明确地赋值执行稍微不同的规则。这就是为什么使方法重载仅在输出/ref值上不同是非法的;CLR不能区分它们!因此,out的类型安全规则必须与ref相同。

out is implemented in terms of ref, the only differences are in what compiles, and the runtime performance will be identical.

out是根据ref实现的,惟一的区别是编译的内容,运行时性能是相同的。

#1


12  

The only difference is a compiler hint.

唯一的区别是编译器提示。

... out ...

…出……

public static void TestOut(out int test)
{
    test = 1;
}

.method public hidebysig static void  TestOut([out] int32& test) cil managed
{
  // Code size       4 (0x4)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stind.i4
  IL_0003:  ret
} // end of method Program::TestOut

... ref ...

…裁判…

public static void TestRef(ref int test)
{
    test = 1;
}

.method public hidebysig static void  TestRef(int32& test) cil managed
{
  // Code size       4 (0x4)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stind.i4
  IL_0003:  ret
} // end of method Program::TestRef

... out and ref are effectively the same. The only real difference being that out tells the compiler to expect the value to be set before the method is returned. You could send a value to a function that has an out flag but again the compiler will treat it as an unassigned variable. The runtime doesn't really care. Both will be created as a pointer to the variable. You are best to use the keyword that describes the functionality you expect with your function. Any optimization that "may" take place in the JITer below this will have near 0 impact on the application.

…out和ref实际上是一样的。唯一的区别是,out告诉编译器在返回方法之前要设置值。你可以将一个值发送给一个带有out标志的函数,但是编译器会把它当作一个未赋值的变量。运行时并不关心。两者都将被创建为一个指向变量的指针。您最好使用关键字来描述您期望的函数的功能。任何“可能”在下面的抖动中发生的优化都会对应用程序产生接近0的影响。

#2


3  

They will most likely be the same at the low-level. If there is a performance difference, it's probably negligible and there are better places to optimize.

在低层次上,它们很可能是相同的。如果存在性能差异,那么它可能是可以忽略的,并且有更好的地方可以优化。

#3


3  

This is a micro-optimization.

这是一个优化上。

Actually, if you have a look at the IL code that is being generated for both options, you'll see no difference. Except for the compiler hint that Matthew Whited indicated:

实际上,如果您看一下为两个选项生成的IL代码,您会发现没有区别。除了马修暗示的编译器:

.method private hidebysig static void  Out([out] valuetype [mscorlib]System.DateTime& d) cil managed

.method private hidebysig static void  Ref(valuetype [mscorlib]System.DateTime& d) cil managed

I'd just suggest the option that is semantically the most correct one for the situation at hand.

我只是建议选择在语义上最适合当前情况的选项。

#4


2  

See this link In particular the section, "Conclusion 4:":

请看这一链接,特别是“结论4:”一节:

"out" and "ref" are actually exactly the same behind the scenes. The CLR only supports "ref"; "out" is just "ref" where the compiler enforces slightly different rules regarding when the variable in question is known to have been definitely assigned. That's why it is illegal to make method overloads that differ solely in out/ref-ness; the CLR cannot tell them apart! Therefore the rules for type safety for out have to be the same as for ref.

“out”和“ref”实际上在幕后是完全相同的。CLR只支持“ref”;“out”仅仅是“ref”,编译器对所讨论的变量何时被明确地赋值执行稍微不同的规则。这就是为什么使方法重载仅在输出/ref值上不同是非法的;CLR不能区分它们!因此,out的类型安全规则必须与ref相同。

out is implemented in terms of ref, the only differences are in what compiles, and the runtime performance will be identical.

out是根据ref实现的,惟一的区别是编译的内容,运行时性能是相同的。