.net 为什么指针是引用类型?
本周我一直在研究一些基于反射的代码,在单元测试期间发现了一个意外情况:指针是引用类型。C#code.net 为什么指针是引用类型?,.net,reflection,.net,Reflection,本周我一直在研究一些基于反射的代码,在单元测试期间发现了一个意外情况:指针是引用类型。C#codetypeof(int).MakePointerType().IsClass返回true 我签入了我刚到达的带注释的CLI标准,果然,指针被明确定义为引用类型 这对我来说是个意外,来自C++背景。我刚才假设指针是值类型 指针类型是引用类型而不是值类型有什么特殊原因吗 更新(澄清) 当谈到指针和引用时,关于“指针”和“指针对象”,事情往往会变得混乱。所以这里有一些澄清 类型可以是引用类型或值类型,但变量
typeof(int).MakePointerType().IsClass
返回true
我签入了我刚到达的带注释的CLI标准,果然,指针被明确定义为引用类型
这对我来说是个意外,来自C++背景。我刚才假设指针是值类型
指针类型是引用类型而不是值类型有什么特殊原因吗
更新(澄清)
当谈到指针和引用时,关于“指针”和“指针对象”,事情往往会变得混乱。所以这里有一些澄清
类型可以是引用类型或值类型,但变量略有不同。(很抱歉,我没有机会阅读我的CLI标准,因此术语和概念可能是错误的-请纠正我!)
给定此代码(引用类型的局部变量概念):
变量x
和y
实际上不是引用类型,但它们是对作为引用类型的对象的引用(MyClass
是引用类型)。换句话说,x
和y
不是引用类型的实例;它们仅引用引用类型的实例
给定此代码(值类型的局部变量概念):
变量x
和y
是实例值类型(或者至少表现为实例)
那么我们来看看这个代码:
var i = 13;
var x = &i;
var y = x;
如果指针类型是引用类型,那么这就是我如何解释语句x=&I
:
int*
的实例,指向i
x
是对该指针实例的引用y=x
时,复制引用。y
和x
都引用指针对象的同一实例来自C++背景的指针对值类型的理解更为合理,因此语句<代码> x=和i >代码>只将代码< >代码>的地址分配给值类型<代码> x>代码>的实例,以及<代码> y= x < /Cord> >将地址值复制到<代码> y>代码>。不会在堆上创建“指针对象”。
它们是引用类型,因为它们不包含目标对象的实际值:就像引用一样,它们只“指向”目标对象。请考虑:MyClass x = new MyClass();
这里,MyClass是一种引用类型,如果您通过反射查看,x将被称为引用类型。但是,在引擎盖下面,x实际上是一个指针。typeof(int).MakePointerType().IsPointer
似乎有区别。这只是一个理论,但它是否与以下事实有关:由于垃圾收集系统和堆压缩,当对象在内存中移动时,指针必须调整。通过创建托管指针引用类型,它们可以以与任何其他引用相同的方式重新指向,而不必将其作为特例 更新 Wesner Moise的一篇优秀文章:“
在本文中,他描述了如何在堆压缩期间调整托管指针 我还没有看到一个完整的答案,所以我现在结束这个问题
我不得不得出结论:指针(例如,
int*
);对于IsClass
,他们的Type
s返回true
,这是规范中的一个错误。我怀疑没有人注意到这一点,因为获取指针类型是一个非常罕见的操作。从type.IsClass上的CLR文档中-'获取一个值,指示该类型是否为类;也就是说,不是“值类型或接口”。从技术上讲,指针类型不是继承自System.Object
,因此它不是对象、值类型或接口,而是文档中的类。指针类型(int*
)与普通对象是完全不同的实体reference@thecoop引用在概念上与指针没有什么不同。两者都包含一些其他数据的内存地址,可以是int
原语或MyClass
对象。主要区别在于引用通常是不可变的(引用本身,而不是它们引用的内容);可以确定引用类型是否为指针。我的问题是为什么指针是引用类型而不是值类型(请参阅更新的问题)。CLR区分托管和非托管指针类型,请参阅CLR规范中分区I的12.1.1.1。托管指针可能会被GC更改(移动)。我认为这可能是它们成为类类型的原因。另请参见第14.4节分区II-特殊类型/指针类型。我更新了这个问题,以便更清楚地说明引用类型与引用变量。我相信指针只能指向固定对象-。不过我会读那篇文章;看起来很有趣!你看到那张照片了吗?根据它的说法:在不安全的上下文中,类型可以是指针类型、值类型或引用类型。所以你不能把它们既当作值类型也当作引用类型吗?这是有道理的。但它并没有回答我的问题:为什么指针引用类型(即,它们从IsClass
返回true
)?请参见图中的另一个自相矛盾的语句。指针列在引用类型下。
var i = 13;
var x = &i;
var y = x;
MyClass x = new MyClass();