C# 是列表<;T>;指针?

C# 是列表<;T>;指针?,c#,list,pointers,C#,List,Pointers,我注意到List的行为不同于其他简单对象,例如String。这个问题可能看起来很新鲜,但这确实打动了我,因为我认为List是简单的对象 以以下代码为例: List<String> ls1 = new List<String>(); ls1.Add("a"); List<String> ls2 = ls1; ls1.Add("b"); 其中,s1在末尾等于b,s2等于a 这意味着List实际上是一个右指针?行s1=“b”实际上为s1分配了一个新的引用s1和s2

我注意到
List
的行为不同于其他简单对象,例如
String
。这个问题可能看起来很新鲜,但这确实打动了我,因为我认为
List
是简单的对象

以以下代码为例:

List<String> ls1 = new List<String>();
ls1.Add("a");
List<String> ls2 = ls1;
ls1.Add("b");
其中,
s1
在末尾等于
b
s2
等于
a

这意味着
List
实际上是一个右指针?

s1=“b”
实际上为
s1
分配了一个新的引用
s1
s2
现在指的是两个不同的对象

ls1
引用的
列表
对象的更改可以通过对该对象的所有引用(包括
ls2
)看到。当你使
ls2=ls1
时,你基本上是说
ls1
ls2
都指向同一个对象。通过引用变量ls1对对象的更改可以通过引用变量ls2查看,因此它的行为类似于指针

String
也是一种引用类型,但字符串是不可变的,在某些情况下,它们的行为类似于值类型(与引用类型不同),因此您在这里会感到困惑


这里有一个很好的解释来解释为什么字符串是这样工作的:

在C中,它们被称为
引用
,而不是
指针
。也许它们是同一件事减去不能将它们转换为整数来打印它们的事实,再减去被禁止的指针算术。从技术上讲,它们是“不透明的”,所以你不(不应该)知道它们是如何工作的。显然,如果使用管理C++(-<)/P>> P>,C语言中的每个对象都是引用,那么这种不透明性就被破坏了。像int、string、char这样的原语不是引用。

string、int、float都是值类型。所以,当你说

String s1 = "a";
String s2 = s1;
s1 = "b";
初始化s2时,s1的值复制到分配给s2的空间中。因此,如果您窥探内存,您可以在内存中的两个不同位置(分配给s1的位置和分配给s2的内存)找到“a”的十六进制表示。但是,如果您尝试对引用类型(如List)执行相同的操作,那么当您说这是一个pass-by-reference时会发生什么情况:

List<String> ls1 = new List<String>();
ls1.Add("a");
List<String> ls2 = ls1;
ls1.Add("b");
List ls1=新列表();
ls1.添加(“a”);
列表ls2=ls1;
ls1.添加(“b”);
具有与堆上分配的列表相对应的对象。查找此对象的位置的地址位于为局部变量s1和s2分配的空间中,而不是位于该空间中的实际值。原因是对象(列表)可能是一个大的对象,并且在程序的整个生命周期中可能存在很长的生命周期,为这样一个对象从堆栈中分配内存会很昂贵。
我建议您阅读本文,以了解CLR如何真正解释值类型和引用类型,它们被称为引用,而不是指针<代码>列表是一个对象,所以是的,它“像一个指针”(我松散地使用这个术语,因为托管代码中的对象不称为“指针”,它们称为引用)。列表和字符串在这方面是相同的。得到不同结果的唯一原因是在这些代码片段中做了不同的事情。对比度
List ls1=新列表();ls1.添加(“a”);ls2=ls1;ls2=新列表();ls2.Add(“b”)
,更接近。或者,为了更清楚地说明这与字符串片段的相同之处,请替换集合初始值设定项:
List ls1=new List{“a”};列表ls2=ls1;ls2=新列表{“b”}。这到底是怎么得到这么多选票的?这不是一个有趣的问题,这只是对作业如何进行的误解。@r0经理:为我的问题辩护,我要说,投票不是为了“有趣”的问题,而是为了“有用且清晰”的问题。我做了一些研究,但没有发现任何结论,因为我有错误的参考术语。抱歉,我的新手问题冒犯了你。:)
行s1=“b”实际上为
分配了一个新的引用-我认为它分配了一个新的值,而不是reference@sll它指派了一个新字符串的引用,您可以从变量的角度考虑一个值,因为字符串是GC堆上管理的引用类型。请参阅(),以获得良好的解释。虽然该值是引用(作为引用类型的变量存储引用),但它为变量指定了一个新值。可能需要注意的是,C#还可以通过
不安全的
代码与指针对话,因此,指针和引用之间又有了一个区别。@MarcGravel同一个词可以有两个不同的概念。在C++/Cli中,您可以管理指针和指针。但它们都被称为“指针”。C#支持不安全的编码并不是因为它使引用成为“引用”,也不是因为它不是“原语”而不是引用类型,而是因为它的值类型——包括
struct
s。我认为将它们称为对象会让人困惑。值类型也从
对象继承。还有一些类型不是原语而是值类型,比如
Guid
。。。嗯,不是真的——一个物体就是一个物体;参考文献是。。。(单词的刮痕)对对象的引用,在堆栈的工作部分,或在字段/本地。当然,
IntPtr
是一种值类型和原语(检查
.IsPrimitive
),并且是一个指针(与引用相关,但与引用不同)。。。funString不是值类型。它的行为类似于值类型,但它是不可变的引用类型。
List<String> ls1 = new List<String>();
ls1.Add("a");
List<String> ls2 = ls1;
ls1.Add("b");