[英]What's the differences between out and int* c#
As far as I read sending out keyword in c#, will change the parameter.据我阅读c#中的发送关键字,将更改参数。 So what's the different between those two cases:
那么这两种情况有什么不同:
using out:用完:
helper(out param){...} func(){ int param = 0; helper(out param)}
using pointer:使用指针:
helper(int* param){..} func(){ int param = 0; helper(¶m)}
Are they same?他们是一样的吗? Tnx.
肿瘤坏死因子。
On the higher level of course there are differences related to how unsafe
code is implemented, such that you can only take pointers to primitive types vs. with the out
keyword any type can be specified as an argument.当然,在更高级别上,
unsafe
代码的实现方式存在差异,例如,您只能将指针指向原始类型,而使用out
关键字可以将任何类型指定为参数。
But it is interesting to see how the two differ down in the lower level assembly code.但有趣的是,这两者在较低级别的汇编代码中有何不同。
Consider the minimum skeleton code.考虑最小的骨架代码。
static class Program
{
static unsafe void Main(string[] args)
{
int x;
SetArg(out x);
Console.WriteLine(x);
int y;
SetArg(&y);
Console.WriteLine(y);
}
static void SetArg(out int x)
{
x = 10;
}
static unsafe void SetArg(int* ptr)
{
*ptr = 10;
}
}
and the resulting assembly code which is inlined以及生成的内联汇编代码
SetArg(out x);
00007FFD4EB80890 int 3
00007FFD4EB80891 sub esp,28h
00007FFD4EB80894 xor eax,eax
00007FFD4EB80896 mov dword ptr [rsp+24h],eax
Console.WriteLine(x);
00007FFD4EB8089A mov ecx,0Ah ! case a)
00007FFD4EB8089F call 00007FFDAA4E2890
int y;
SetArg(&y);
00007FFD4EB808A4 lea rcx,[rsp+24h]
00007FFD4EB808A9 mov dword ptr [rcx],0Ah ! case b)
Console.WriteLine(y);
00007FFD4EB808AF mov ecx,dword ptr [rsp+24h]
00007FFD4EB808B3 call 00007FFDAA4E2890
00007FFD4EB808B8 nop
00007FFD4EB808B9 add rsp,28h
00007FFD4EB808BD ret
In the first case with the out
statement, the value 10 = 0Ah
is written directly to a register ecx
before being written to the console by the Writeline()
function.在使用
out
语句的第一种情况下,值10 = 0Ah
在通过Writeline()
function 写入控制台之前直接写入寄存器ecx
。 This is super optimized as no memory is utilized in this operation.这是超级优化的,因为在此操作中没有使用 memory。 This is why it is not recommended to micro optimize your code, and just convey intent with the
ref/out
keywords and let the compiler do its job.这就是为什么不建议对您的代码进行微优化,而只使用
ref/out
关键字传达意图并让编译器完成其工作的原因。
In the second case with the int*
argument, the value 10 = 0Ah
is written to a memory address on the stack corresponding to the function argument and then loaded up to ecx
from that address before calling Writeline()
.在带有
int*
参数的第二种情况下,值10 = 0Ah
被写入堆栈上与 function 参数对应的 memory 地址,然后在调用Writeline()
之前从该地址加载到ecx
。 Here the code is not only unsafe but also less optimized as the programmer forced the compiler to store the intermediate value in the stack before usage.这里的代码不仅不安全,而且优化程度较低,因为程序员强制编译器在使用前将中间值存储在堆栈中。
Note than an alternate definition of SetArg()
is请注意,
SetArg()
的替代定义是
static unsafe void SetArg(int* ptr)
{
ptr[0] = 10; // same as ptr* = 10
}
but this highlights another potential problem.但这凸显了另一个潜在问题。 Buffer overrun, or out of bounds memory access, because if you had written
缓冲区溢出,或超出范围 memory 访问,因为如果你写
ptr[-1] = 10;
or anything else other than ptr[0]
which is the intended memory location, then you have corrupted the process memory causing havok.或除
ptr[0]
之外的任何其他东西,这是预期的 memory 位置,那么您已经破坏了导致破坏的进程 memory。
These two things are conceptually similar.这两件事在概念上是相似的。 The key difference here is:
这里的主要区别是:
int*
is an unmanaged pointer int*
是一个非托管指针ref int
is a managed pointer ref int
是托管指针out int
is really just ref int
with some extra compiler guard rails around definite assignment out int
实际上只是ref int
在明确分配周围有一些额外的编译器护栏So: what is the difference between a managed and unmanaged pointer?那么:托管指针和非托管指针有什么区别? The key differences:
主要区别:
unsafe
unsafe
Conversely:反过来:
So: in any scenario where you can use a managed pointer ( ref
or out
), in place of an unamnaged pointer: you should .所以:在任何可以使用托管指针(
ref
或out
)代替未管理指针的情况下:你应该. Honestly, very few C# developers fully understand the nuances of managed pointers, but even fewer fully understand the nuances of unamnaged pointers.老实说,很少有 C# 开发人员完全理解托管指针的细微差别,但完全理解未管理指针的细微差别的就更少了。
The use cases are not same as the keywords name suggests.用例与关键字名称所暗示的不同。
The out is a keyword in C# which is used for the passing the arguments to methods as a reference type. out 是 C# 中的一个关键字,用于将 arguments 作为引用类型传递给方法。 It is generally used when a method returns multiple values.
它通常在方法返回多个值时使用。 The out parameter does not pass the property.
out 参数不传递属性。
The pointer in C# which is used for the passing the arguments by a reference. C# 中的指针,用于通过引用传递 arguments。 Or we can say that if any changes made in this argument in the method will pointer reflect in that variable when the control return to the calling method.
或者我们可以说,如果方法中此参数的任何更改将在控件返回调用方法时将指针反映在该变量中。
Pointers are typically there to interop with C++ and aren't to be used in day to day C# coding.指针通常用于与 C++ 互操作,并且不用于日常 C# 编码。 We can use ref type.
我们可以使用 ref 类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.