本周我一直在研究一些基于反射的代码,并且在单元测试期间发现了一个意外情况:指针是引用类型。 C#代码typeof(int).MakePointerType().IsClass
返回true
。
我检查了刚刚到达的Annotated CLI标准,果然,指针被明确定义为引用类型。
这对我来说很奇怪,来自C ++背景。我只是假设指针是值类型。
指针类型是引用类型而不是值类型是否有特殊原因?
更新(澄清)
在谈论指针和引用时,关于“指针”和“指针”的事情常常令人困惑。所以这里有一些澄清。
类型可以是引用类型或值类型,但变量有点不同。 (对不起,我没有机会阅读我的CLI标准,因此术语和概念可能有误 - 请纠正我!)
给定此代码(引用类型的局部变量概念):
var x = new MyClass();
var y = x;
变量x
和y
实际上不是引用类型,但它们是对作为引用类型的对象的引用(MyClass
是引用类型)。换句话说,x
和y
不是引用类型的实例;它们只引用引用类型的实例。
给定此代码(值类型的局部变量概念):
var x = 13;
var y = x;
变量x
和y
是实例值类型(或者至少就像它们的实例一样)。
那么我们来看看这段代码:
var i = 13;
var x = &i;
var y = x;
如果指针类型是引用类型,那么这就是我解释语句x = &i
的方式:
int*
类型的实例,指向i
。x
是对此指针实例的引用。y = x
时,将复制引用。 y
和x
都引用指针对象的相同实例。也许我在这种解释中完全错了。
来自C ++背景,对于指针是值类型更有意义,因此语句x = &i
只是将i
的地址分配给值类型的实例{ {1}}和x
个将价值转换为y = x
的副本。不会在堆上创建“指针对象”。
答案 0 :(得分:4)
我还没有看到完整的答案,所以我暂时关闭这个问题。
我不得不总结:指针(例如,int *
)are actually value types; Type
true
为IsClass
返回{{1}}这一事实在规范中是错误的。我怀疑没有人注意到这一点,因为获取指针类型是一种非常罕见的操作。
答案 1 :(得分:3)
答案 2 :(得分:1)
答案 3 :(得分:0)
它们是引用类型,因为它们不包含目标对象的实际值:就像引用一样,它们只是“指向”目标对象。
答案 4 :(得分:-2)
考虑:
MyClass x = new MyClass();
这里,MyClass是一个引用类型,如果你查看反射,x将被称为引用类型。但是,在引擎盖下,x实际上是一个指针。