我不太理解C#引用和指针之间的区别。它们都指向内存中的位置,对吧?我唯一能想到的区别是,指针不如引用聪明,不能指向堆上的任何内容,免于垃圾回收,并且只能引用结构体或基本类型。
我问这个问题的原因之一是,有一种看法认为人们需要很好地理解指针(来自C语言),才能成为一个好的程序员。许多学习高级语言的人都错过了这一点,因此他们有这种弱点。
我就是不明白指针有什么复杂的?它基本上只是指向内存中的一个位置,对吧?它可以返回其位置并直接与该位置的对象交互?
我错过了重要的一点吗?
我不太理解C#引用和指针之间的区别。它们都指向内存中的位置,对吧?我唯一能想到的区别是,指针不如引用聪明,不能指向堆上的任何内容,免于垃圾回收,并且只能引用结构体或基本类型。
我问这个问题的原因之一是,有一种看法认为人们需要很好地理解指针(来自C语言),才能成为一个好的程序员。许多学习高级语言的人都错过了这一点,因此他们有这种弱点。
我就是不明白指针有什么复杂的?它基本上只是指向内存中的一个位置,对吧?它可以返回其位置并直接与该位置的对象交互?
我错过了重要的一点吗?
指针和引用之间存在微小但极其重要的区别。指针指向内存中的一个位置,而引用指向内存中的一个对象。指针在类型安全方面不具备保障,因为你无法保证它们指向的内存的正确性。
以以下代码为例:
int* p1 = GetAPointer();
在类型安全方面,GetAPointer必须返回与int*兼容的类型。但是仍然不能保证*p1实际上将指向int。它可能是char、double或仅是指向随机内存的指针。
但是,引用指向特定对象。对象可以在内存中移动,但引用不会失效(除非使用不安全代码)。在这方面,引用比指针更安全。
string str = GetAString();
在这种情况下,str有两种状态:1)它指向空对象,因此为null;2)它指向一个有效的字符串。就是这样。CLR保证这种情况存在。它不会对指针进行此类保证。C# 引用可以被垃圾收集器重定位,但普通指针是静态的。因此,在获取数组元素的指针时,我们使用 fixed
关键字来防止其被移动。
编辑:从概念上讲,是的。它们基本上是相同的。
引用是一个“抽象”的指针:您不能对引用进行算术运算,也不能使用其值进行任何低级技巧。
null
或者标识其正确类型的对象。Object
被用作东西时)。虽然系统为每个对象保留了一些位数据以供GetHashCode
使用,但对象除了存在到它们的引用集合外没有真正的身份。如果X
持有一个对象的唯一引用,将X
替换为具有相同字段内容的新对象的引用将没有可识别的影响,甚至连这种影响也不能保证。指针可以指向应用程序地址空间中的任何字节。 引用受.NET环境严格限制、控制和管理。
与指针相比,引用的最大优点是更加简单易读。当你简化某些东西时,通常会使其更易于使用,但代价是失去了低级别操作所具有的灵活性和控制(正如其他人所提到的)。
指针经常因为“丑陋”而受到批评。
class* myClass = new class();
现在每次使用它时,您都需要先取消引用它,方法是
myClass->Method() or (*myClass).Method()
MyMethod(&type parameter)
{
parameter.DoThis()
parameter.DoThat()
}
.
的地方改用 ->
,那么C#将会是一种更好的语言。但是 foo.bar(123)
与对静态方法 fooClass.bar(ref foo, 123)
的调用是同义的。这将允许诸如 myString.Append("George")
这样的事情;[这将修改 变量 myString
],并更明显地显示了 myStruct.field = 3;
和 myClassObject->field = 3;
之间的差异。 - supercat