在我深入研究设计课程之前,我只想检查一下我对C#处理事物的方式的理解。我目前的理解是:
Struct
是值类型,这意味着它实际上包含在其中定义的数据成员。 Class
是引用类型,这意味着它包含对其中定义的数据成员的引用。
方法签名通过 value 传递参数,这意味着将值的副本传递给方法内部,这使得大型数组和数据结构的代价很高。
我不明白当我调用一个方法时会发生什么,实际发生了什么。是否会调用new()?它只是自动复制数据吗?或者它实际上只是指向原始对象?如何使用 ref 和 out 来影响这个?
答案 0 :(得分:12)
我不明白当我调用一个方法时会发生什么,实际发生了什么。是否会调用new()?它只是自动复制数据吗?或者它实际上只是指向原始对象?使用ref和out如何影响这个?
不会自动调用空构造函数,它实际上只指向原始对象 使用ref和out不会影响这一点。
我认为理解C#如何处理向函数传递参数会更容易
实际上一切正在传递按值
的真的?一切都是有价值的吗?
是!一切!
当然,传递类和简单类型对象(如Integer)之间必然存在某种差异,否则,这将是性能方面的巨大退步。
嗯,事实上,当你将一个对象的类实例传递给一个函数时,在实际传递给该函数的是指向该类的指针。当然,指针可以通过值传递而不会导致性能问题。
实际上,一切都是按价值传递的;只是那个时候 你正在“传递一个对象”,你实际上是在传递一个对象 对象(并且您通过值传递该引用)。
一旦我们进入函数,给定参数指针,我们可以与通过引用传递的对象相关联。。
你实际上并不需要为此做任何事情,你可以直接与作为参数传递的实例相关联(如前所述,整个过程在幕后完成)。
在理解了这一点之后,您可能会理解空构造函数不会被自动调用,而实际上只是指向原始对象。
已编辑:
对于 out 和 ref ,它们允许函数更改参数的值,并使更改保持在函数范围之外。
简而言之,对值类型使用ref关键字的行为如下:
int i = 42;
foo(ref i);
将在c ++中翻译为:
int i = 42;
int* ptrI = &i;
foo(ptrI)
虽然省略ref只会转换为:
int i = 42;
foo(i)
对引用类型对象使用这些关键字,将允许您将内存重新分配给传递的参数,并使重新分配在函数范围之外保持不变(有关详细信息,请参阅{ {3}})
旁注:
ref和out之间的区别在于out确保被调用函数必须为out参数赋值,而ref没有这个限制,然后你应该通过自己分配一些默认值来处理它,因此,ref意味着参数的初始值对函数很重要,可能会影响它的行为。
答案 1 :(得分:5)
将值类型变量传递给方法意味着将变量的副本传递给方法。对方法内发生的参数的任何更改都不会影响存储在变量中的原始数据。
如果希望被调用的方法更改参数的值,则必须使用ref或out关键字通过引用传递它。
按值传递reference-type参数时,可以更改引用指向的数据,例如类成员的值。但是,您无法更改引用本身的值;也就是说,您不能使用相同的引用为新类分配内存并使其在块外保留。为此,请使用ref(或out)关键字传递参数。
答案 2 :(得分:0)
可悲的是,没有办法在C#或VB.NET中按值传递对象。我建议你通过,例如,New Class1(Object1),其中Object1是Class1的一个实例。您必须编写自己的新方法来执行此操作,但至少您可以为Class1提供简单的按值传递功能。