首页 新闻 赞助 找找看

C# 结构类型的数组能通过索引修改结构的数据,为什么结构类型的集合却直接编译报错了

0
悬赏园豆:10 [已解决问题] 解决于 2021-08-25 10:21

static void AAA() {
Test[] ts = new Test[1];
ts[0] = new Test(1, "a");
ts[0].a = 123; //完全没有问题
}
static void BBB() {
List<Test> ts = new List<Test>();
ts.Add(new Test(1, "a"));
ts[0].a = 123; //直接报错,说是“无法修改xxx的返回值,因为它不是变量”
}
struct Test {
public int a;
public string b;
public Test(int a, string b) {
this.a = a;
this.b = b;
}
}
是因为数组索引直接是指向了结构的地址,然后修改地址内存中的数据不报错,而集合是通过索引器返回拷贝的结构体,修改拷贝的数据没有意义,所以微软直接给报错了吗

WmW的主页 WmW | 菜鸟二级 | 园豆:424
提问于:2021-08-10 12:01
< >
分享
最佳答案
0

你理解的是正确的,微软源头上直接禁止了这种操作。

解决办法:

1.改成class引用类型,这样,就成了一个对象(引用类型),就会返回在堆上的实际地址,修改也会反映到实际的对象

2.设置一个中间临时变量,然后再替换整个原来的struct值。这样实际上是替换整个struct。

收获园豆:10
熊泽-学习中的苦与乐 | 老鸟四级 |园豆:2267 | 2021-08-11 09:29
其他回答(1)
0

根本原因是:

不管存的是什么,数组返回的是对象引用,List<T>返回的是对应的泛型类型,返回值类型时不能直接修改其数据。
List<T>底层也是通过数组实现的,就是返回的时候会转换成对应的泛型类型。

数组索引器返回时会新建一个对象指向对应索引下的内容(值也是一个特殊的对象)并返回其引用,对于值类型返回的引用和值的变量名起到的作用是一样的,所以能在返回的引用上访问结构体的成员。

二次元攻城狮 | 园豆:462 (菜鸟二级) | 2021-08-13 16:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册