通过引用和值传递对象

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

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

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

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

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

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

简短的回答:

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

答案很长:

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

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

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

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

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

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


编辑:

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

 int i = 42; foo(ref i); 

将在c ++中翻译为:

 int i = 42; int* ptrI = &i; foo(ptrI) 

省略ref只会转换为:

 int i = 42; foo(i) 

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

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

将值类型变量传递给方法意味着将变量的副本传递给方法。 对方法内发生的参数的任何更改都不会影响存储在变量中的原始数据。

如果希望被调用的方法更改参数的值,则必须使用ref或out关键字通过引用传递它。

按值传递reference-type参数时,可以更改引用指向的数据,例如类成员的值。 但是,您无法更改引用本身的值; 也就是说,您不能使用相同的引用为新类分配内存并使其在块外部保留。 为此,请使用ref(或out)关键字传递参数。

参考: 传递参数(C#)

可悲的是,没有办法在C#或VB.NET中按值传递对象。 我建议您传递,例如,New Class1(Object1),其中Object1是Class1的一个实例。 您必须编写自己的New方法来执行此操作,但至少您可以为Class1提供简单的按值传递function。