是列表<;T>;指针
本文关键字:指针 gt lt 列表 | 更新日期: 2023-09-27 18:11:48
我注意到List<T>
的行为与其他简单对象不同,例如String
。这个问题可能看起来很新鲜,但这确实让我印象深刻,因为我认为List<T>
是简单的对象。
以以下代码为例:
List<String> ls1 = new List<String>();
ls1.Add("a");
List<String> ls2 = ls1;
ls1.Add("b");
最后,ls1
将等于{"a", "b"}
,ls2
也将等于。这与此代码的行为完全不同:
String s1 = "a";
String s2 = s1;
s1 = "b";
其中s1
在末尾等于b
,s2
等于a
。
这意味着List<T>
实际上是一个指针,对吧?
List<T>
是一个引用类型,所以是的,它的行为就像一个指针。
String
也是一个引用类型,但字符串是不可变的,在某些情况下,它们的行为类似于值类型(与引用类型相反(,因此您在这里感到困惑。
这里有一个很好的解释来解释为什么字符串以这种方式工作:在C#中,为什么字符串是一个行为类似于值类型的引用类型?
行s1 = "b"
实际上为s1
分配了一个新的引用。CCD_ 16和CCD_。
ls1
引用的对List<string>
对象的更改通过对该对象的所有引用(包括ls2
(可见。当你制作ls2 = ls1
时,你基本上是说ls1
和ls2
都引用了同一个对象。经由参考变量ls1
对对象的改变经由参考变量ls2
可见。
在C#中,它们被称为references
,而不是pointers
。也许它们是一样的,减去不能将它们强制转换为整数以打印它们的事实,再减去禁止的指针算术。从技术上讲,它们是"不透明的",所以你不应该知道它们是如何工作的。很明显,如果您使用托管C++:-(
C#中的每个对象都是引用。像int、string、char这样的基本体不是引用。
String、int、float都是值类型。所以,当你说
String s1 = "a";
String s2 = s1;
s1 = "b";
初始化s2时,s1的值被复制到分配给s2的空间中。因此,如果您窥探内存,您可以在内存中的两个不同位置(分配给s1的位置和分配给s2的内存(找到"a"的十六进制表示。但是,如果你试图对引用类型做同样的事情,比如List,当你说这样的话时,会发生什么是一个传递引用:
List<String> ls1 = new List<String>();
ls1.Add("a");
List<String> ls2 = ls1;
ls1.Add("b");
是具有与堆上分配的List相对应的对象。查找该对象的地址位于为局部变量s1和s2分配的空间上,而不是位于该空间中的实际值。原因是对象(List(可能是一个很大的对象,并且可能在程序的整个生命周期中使用很长时间,并且为这样的对象从堆栈中分配内存会很昂贵。我建议您阅读这个问题线程,以了解CLR 如何真正解释值类型和引用类型