为什么指针引用类型?

时间:2010-07-23 11:10:00

标签: .net reflection

本周我一直在研究一些基于反射的代码,并且在单元测试期间发现了一个意外情况:指针是引用类型。 C#代码typeof(int).MakePointerType().IsClass返回true

我检查了刚刚到达的Annotated CLI标准,果然,指针被明确定义为引用类型。

这对我来说很奇怪,来自C ++背景。我只是假设指针是值类型。

指针类型是引用类型而不是值类型是否有特殊原因?

更新(澄清)

在谈论指针和引用时,关于“指针”和“指针”的事情常常令人困惑。所以这里有一些澄清。

类型可以是引用类型或值类型,但变量有点不同。 (对不起,我没有机会阅读我的CLI标准,因此术语和概念可能有误 - 请纠正我!)

给定此代码(引用类型的局部变量概念):

var x = new MyClass();
var y = x;

变量xy实际上不是引用类型,但它们是对作为引用类型的对象的引用(MyClass是引用类型)。换句话说,xy不是引用类型的实例;它们只引用引用类型的实例。

给定此代码(值类型的局部变量概念):

var x = 13;
var y = x;

变量xy是实例值类型(或者至少就像它们的实例一样)。

那么我们来看看这段代码:

var i = 13;
var x = &i;
var y = x;

如果指针类型引用类型,那么这就是我解释语句x = &i的方式:

  1. 创建了int*类型的实例,指向i
  2. 由于指针是引用类型,因此在堆上创建此实例(假设所有引用类型都放在堆上,这是一个实现细节)。
  3. x是对此指针实例的引用。
  4. 指针实例最终将被垃圾收集,就像其他引用类型一样。
  5. 执行y = x时,将复制引用。 yx都引用指针对象的相同实例。
  6. 也许我在这种解释中完全错了。

    来自C ++背景,对于指针是值类型更有意义,因此语句x = &i只是将i的地址分配给值类型的实例{ {1}}和x个将价值转换为y = x的副本。不会在堆上创建“指针对象”。

5 个答案:

答案 0 :(得分:4)

我还没有看到完整的答案,所以我暂时关闭这个问题。

我不得不总结:指针(例如,int *are actually value types; Type trueIsClass返回{{1}}这一事实在规范中是错误的。我怀疑没有人注意到这一点,因为获取指针类型是一种非常罕见的操作。

答案 1 :(得分:3)

答案 2 :(得分:1)

答案 3 :(得分:0)

它们是引用类型,因为它们不包含目标对象的实际值:就像引用一样,它们只是“指向”目标对象。

答案 4 :(得分:-2)

考虑:

MyClass x = new MyClass();

这里,MyClass是一个引用类型,如果你查看反射,x将被称为引用类型。但是,在引擎盖下,x实际上是一个指针。