如果类是引用,则c#引用如何工作
class1 a = new class1();
因此地址“ a”包含
指示mem [0]的对象的地址,所以它是一个指针
为什么
method(class1 a);
将对象的值复制到本地方法实例而不是mem [0]的地址吗?
是否隐式取消引用(*
)a?
如果是这样,那么ref
修饰符会取消它吗?
让我们说一个类定义一种地址类型,以指向指向对象各个点的地址。我仍然无法结束...
答案 0 :(得分:2)
为什么
method(class1 a)
将对象的值复制到本地方法
这是一个错误的假设。方法参数a
包含对该对象的引用。如果您使用method(ref class1 a)
,则会获得对传递给方法的变量的引用,该变量又包含对对象的引用
给予
class1 a = new class1();
method(ref a);
在方法中,您可以为参数分配一个新对象,这将更改a
!
void method(ref class1 b)
{
b = new class1(); // This changes a!
}
如果缺少ref
关键字,则该方法将获取引用的副本(而不是对象的副本!)
void method(class1 b)
{
b = new class1(); // This does NOT change a.
// But
b.IntProperty = 5; // This changes a property of a.
}
在C#中,您不必使用*
。 C#知道哪些类型是引用,哪些类型是值类型,并对其进行相应处理。
对于常规参数:
null
)。即,没有对象被复制。对于ref
参数:
null
)的变量的引用。换句话说,对于ref
参数,参数名称只是方法调用中使用的变量的别名。
如果发现此问题令人困惑,则有助于在编辑器中配置颜色,以帮助区分引用类型和值类型。在Visual Studio中:转到菜单Tools
> Options...
,然后依次转到Environment
> Fonts and Colors
并更改User Types - Structures
的颜色(即值类型)以显示为不同的颜色作为类(我正在使用Olive)。您还可以更改其他User Types
(我将红色用于代表,将深橙色用于枚举,将紫色用于接口,将一种霓虹绿色用于类型参数。
答案 1 :(得分:1)
您将必须了解如何调用方法以及如何在内存中分配对象。
所有类类型都是C#中的引用类型-从 System.Object 继承。
支持.NET Framework类层次结构中的所有类以及 为派生类提供底层服务。这是终极的 .NET Framework中所有类的基类;这是 类型层次结构。
参考:MSDN Documentation of System.Object
意味着,它们将在堆中分配。他们的参考文献将被复制到某个地方。该变量保存引用被复制的地方。
在方法调用的情况下,将对象的地址复制到调用堆栈。它指向相同的地址。
因此,即使您更改了该类的任何属性(值类型),即使您不使用ref关键字,您仍然可以在调用者方法中访问更改后的值。
void Method(Class A)
从技术上讲,ref关键字提供相同的地址位置-而不是将此地址复制到新位置。
希望这能回答您的查询。
答案 2 :(得分:1)
是的,从这个意义上讲,您可能想将C#类变量视为(安全的)C指针。它们只是不允许您操纵它们指向内存的位置(甚至允许运行时重新分配和移动它们)。
如果您的class1
是类类型(而不是struct类型或ValueType),那么您不正确地认为method
将复制整个a
对象。相反,它的作用就像您在C中传递了一个指针。但是就像在C中一样,*p1==*p2
和p1==p2
但&p1!=&p2
由于类变量仅存储引用(类似于C指针),因此如果method
突变了a
所引用的对象,则这些突变将在method
返回后保留。然后,通过ref传递类变量类似于将指针传递给C中的指针。但是在C#中几乎不可能是一个好的设计思想。
这是 class 变量(包括字符串)的行为方式。但是,还有值类型(除字符串和对象以及结构以外的所有基本类型)在赋值时被复制,除非通过ref或out传递。
进一步阅读: