private static readonly List<string> Phones = new List<string>() { "12222222222", "1322222222" }; List<string> phones = Phones; phones.Add("13333333333");
phones:"12222222222", "1322222222","13333333333"
Phones:怎么也是这个?"12222222222", "1322222222","13333333333"
不明白那个地方写得有问题,还是?
觉得好像是List<string> phones=Phones的原因
这个原因我找到了,但是就是不知道为什么
@K战神: 首先你给list的Phones赋值且又将值赋予了list的phones,将2个list集合关联起来,顾名思义为引用类型,当你输出两个list集合时那两个list集合的值就是一样的了;但是如果你将phones的值赋值为null,那两个list就不会有引用类型存在不相关联了,因此值就不一样了,你可以试试分别输入两个list集合
看不出有什么问题,一切都很正常.也不知道你的问题是什么
我没有对Phones进行操作,但是也添加了"13333333333"
@K战神: 你需要弄明白引用或者指针的概念,
引用指向一个变量,你用2个引用指向同一个变量
@吴瑞祥: 嗯,我想多了,就是同时指向了一个引用地址,导致的结果。
输出没有问题
Phones标记为static readonly,只是说无法对Phones赋值,但是并不影响它作为list对象的其他操作。
List<string> phones = Phones; phones.Add("13333333333");
这里新建了一个phones对象,其实phones就指向Phones,那么你对phones的添加删除都会影响Phones的,所以跟直接操作Phones(add/remove)操作是一样的,但是phones和Phones又有个区别就是phones是可被赋值的
LIST是一个引用类型的,List<string> phones = Phones;你这样是2个指向了一个相同的引用,这样你改变phones 的值也就会改变Phones的值,你发现没有,你这样可以改变只读变量的值,和我上次用反射改变是差不多
要是想要list变成readonly 可以用 .AsReadOnly();
ReadOnlyCollection<string> Phones = new List<string>{"123","456"}.AsReadOnly();
虽然这个问题已解决了,但是还想说两句。看了这个问题,其实我的脑子里已经有了点东西,但是还是到VS中敲了一些实际的代码做了验证。看到结果后,脑子里的东西就清晰起来了。
首先说一点,楼主的问题跟第二个本地变量phones一点儿关系都没有,不信的话,楼主可以试着将phones变量相关的代码注释掉,然后在方法中对Phones直接调用Add等List集合相关的方法,你会发现Phones一样可以增加新的元素(或移除等其他操作)。
下面我说说我的理解,静态只读是修饰变量的,当你的成员变量定义为静态只读时,它只能由初始化器或静态构造函数赋值,赋值是什么意思?由于你的变量类型是引用类型,因此赋值是在托管堆中分配一个空间用来存储实例对象,同时将这个空间的引用地址放到变量Phones的堆栈中(这里说得可能不准确,我对内存分配这块理解得不是很透,但是大概是这个意思),赋值是跟管理集合内部元素一点关系都没有的意思。而你在托管堆中存储的实例对象是List泛型集合对象,很不幸List泛型集合是一个容器类型的对象,它的实质是数组。如果你对数组熟悉的话,接下来可以用数组的概念来理解,就是说数组本身不可变(只读),但是数组中的元素是可以改变的,集合也是类似(当然肯定也会有一点点差别,不过不影响大局)。所以这里不要纠结把静态只读变量赋值给一个本地变量后,调用本地变量的Add方法为什么会改变静态只读变量的元素,因为你完全可以直接调用静态只读变量的Add方法来改变其元素。那么静态只读是不是就失效了呢?我猜你的初衷是想禁止改变这个静态只读变量的值(包括里面的元素),但是你要明白它的静态只读只是针对变量赋值,而不是针对变量里面的具体元素。要想实现你的初衷,你可以尝试这种写法:List<string> phones=new List<string>();phones.AddRange(Phones);。