通过引用和值传递对象

Kyl*_*ran 11 c# parameter-passing pass-by-reference pass-by-value

在深入研究设计课程之前,我只想检查一下我对C#处理事物的方式的理解.我目前的理解是:

  • Struct是一个类型,这意味着它实际上包含在其中定义的数据成员.
  • Class是一种引用类型,意味着它包含对其中定义的数据成员的引用.

  • 方法签名按传递参数,这意味着的副本将传递到方法内部,这使得大型数组和数据结构的代价很高.

  • 使用refout关键字定义参数的方法签名将通过引用传递参数,这意味着提供了指向对象的指针.

我不明白的是当我调用一个方法时会发生什么,实际发生了什么.是否会调用new()?它只是自动复制数据吗?或者它实际上只是指向原始对象?使用refout如何影响这个?

Avi*_*ner 13

我不明白的是当我调用一个方法时会发生什么,实际发生了什么.是否会调用new()?它只是自动复制数据吗?或者它实际上只是指向原始对象?使用ref和out如何影响这个?

简短的回答:

不会自动调用空构造函数,它实际上只指向原始对象.
使用ref和out不会影响这一点.

答案很长:

我认为理解C#如何处理向函数传递参数会更容易.
实际上一切都是通过价值传递
真的吗?!一切都是有价值的吗?
是! 一切!

当然,传递类和简单类型对象(如Integer)之间必然存在某种差异,否则,这将是性能方面的巨大后退.

嗯,就是在幕后,当你将一个对象的类实例传递给一个函数时,真正传递给该函数的是指向该类的指针.当然,指针可以通过值传递而不会导致性能问题.

实际上,一切都是通过价值传递的; 只是当你"传递一个对象"时,你实际上是在传递对该对象的引用(并且你通过值传递该引用).

一旦我们在函数中,给定参数指针,我们就可以与通过引用传递的对象相关联.
您实际上不需要为此做任何事情,您可以直接与作为参数传递的实例相关联(如前所述,整个过程在幕后完成).

理解了这一点之后,你可能会理解空构造函数不会被自动调用,它实际上只是指向原始对象.


编辑:

对于outref,它们允许函数更改参数的值,并使该更改在函数范围之外保持不变.
简而言之,对值类型使用ref关键字将如下所示:

int i = 42;
foo(ref i);
Run Code Online (Sandbox Code Playgroud)

将在c ++中翻译为:

int i = 42;    
int* ptrI = &i;
foo(ptrI)
Run Code Online (Sandbox Code Playgroud)

省略ref只会转换为:

int i = 42;
foo(i)
Run Code Online (Sandbox Code Playgroud)

使用这些关键字作为引用类型对象,将允许您将内存重新分配给传递的参数,并使重新分配在函数范围之外保持不变(有关更多详细信息,请参阅MSDN页面)

旁注:
ref和out之间的区别在于out确保被调用函数必须为out参数赋值,而ref没有这个限制,然后你应该通过自己分配一些默认值来处理它,因此, ref表示参数的初始值对函数很重要,可能会影响它的行为.


Sab*_*van 5

Passing a value-type variable to a method means passing a copy of the variable to the method. Any changes to the parameter that take place inside the method have no affect on the original data stored in the variable.

If you want the called method to change the value of the parameter, you have to pass it by reference, using the ref or out keyword.

When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref (or out) keyword.

Reference: Passing Parameters(C#)