通过引用与值传递对象
本文关键字:对象 值传 引用 | 更新日期: 2023-09-27 18:20:37
在深入设计类之前,我只想检查一下我对C#处理问题的方式的理解。我目前的理解是:
Struct
是值类型,这意味着它实际上包含在中定义的数据成员-
Class
是引用类型,这意味着它包含对中定义的数据成员的引用。 -
方法签名通过值传递参数,这意味着该值的副本会传递到方法内部,这对于大型数组和数据结构来说成本高昂。
- 使用ref或out关键字定义参数的方法签名将通过引用传递参数,这意味着将提供指向对象的指针
我不明白的是,当我调用一个方法时会发生什么,实际会发生什么。是否调用new()?它只是自动复制数据吗?或者它实际上只是指向原始对象?使用ref和out如何影响这一点?
我不明白的是,当我调用一个方法时会发生什么,实际会发生什么。是否调用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)
对引用类型对象使用这些关键字,将允许您将内存重新分配给传递的参数,并使重新分配在函数范围之外持续存在(有关更多详细信息,请参阅MSDN页面)
旁注:
ref和out的区别在于,out确保被调用的函数必须为out参数赋值,而ref没有这个限制,然后你应该通过自己赋值来处理它,因此,ref意味着参数的初始值对函数很重要,可能会影响它的行为。
如果希望被调用的方法更改参数的值,则必须使用ref或out关键字通过引用传递。
按值传递引用类型参数时,可以更改引用所指向的数据,例如类成员的值。但是,不能更改引用本身的值;也就是说,不能使用相同的引用为新类分配内存,并使其在块外持久存在。为此,请使用ref(或out)关键字传递参数。
参考:传递参数(C#)
不幸的是,在C#或VB.NET中没有按值传递对象的方法。我建议您传递,例如,NewClass1(Object1),其中Object1是Class1的实例。要做到这一点,您必须编写自己的New方法,但至少可以为Class1提供一个简单的值传递功能。