作者mark0708 (sheep)
看板C_Sharp
标题[问题] Var 使用上的一点小问题
时间Sat Feb 8 00:34:32 2020
VS 2010 + .NET 4.0
最近在写C# 常常用
foreach (var v in class)
{
string s = v.name;
}
读的时候没什麽问题只要传进去的东西已经写好 看起来都OK
问题在指定一个已经初始化的结构时
常常会有针对 结构内成员进行 Array.resize时 用监看视看时
var内的 array 被程式 从 null 被resize成我要的大小
但是原先的 却还是null
ex:
var varTemp = LoadData;
Array.resize( ref v.GroupInfo, 10); // GroupInfo 也是一个结构阵列
// public SomeStruct[] GroupInfo;
在这时去进行监看 会发现 varTemp.GroupInfo 有10组可设定
但是原先的LoadData.GroupInfo 依旧维持 null
但是也不是都这样 另外的 LoadData.metadat[].GroupInfo 两边就都是同步的
目前是先处理完後 多写一行 LoadData = varTemp 去避免这问题...
但是还是问一下有没有人了解原因
--
如果你对我说,你想要一朵花,那麽我就会给你一朵花。
如果你对我说,你想要一颗星星,那麽我就会给你一颗星星。
如果你对我说,你想要一场雪,那麽我就会给你一场雪。
如果你对我说,你想要离开我,那麽我会说,我会对你说,我给你自由。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 219.87.175.130 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1581093325.A.1F5.html
1F:推 s4300026: 所以resize是回传新物件 02/08 13:33
2F:推 s4300026: 以游戏比喻:你有个朋友是武器锻造商,你用下列两种方 02/08 14:08
3F:→ s4300026: 式去请朋友帮你加工新武器。1.1你有把武器,你给它贴上 02/08 14:08
4F:→ s4300026: 两个标签,分别为 “加工前” 和 “加工後”。1.2你把贴 02/08 14:08
5F:→ s4300026: 有 “加工後” 标签的武器交给朋友,请它依此为蓝本, 02/08 14:08
6F:→ s4300026: 打造一把新武器。1.3然後把名为 “加工後” 的标签贴在 02/08 14:09
7F:→ s4300026: 新武器上!2.1你有个仓库里面有一把贴有 “攻城专用” 02/08 14:09
8F:→ s4300026: 的武器2.2你跟朋友说你去仓库,找贴有“攻城专用”的武 02/08 14:09
9F:→ s4300026: 器,并依此打造一把新的2.3把打造好的武器塞回原仓库, 02/08 14:09
10F:→ s4300026: 然後把贴纸 “攻城专用” 黏到新武器上。-------------- 02/08 14:09
11F:→ s4300026: --------------------------请拿两只笔,两个标签纸模 02/08 14:09
12F:→ s4300026: 拟上述情境。以上是我觉得这就是原因啦。 02/08 14:09
13F:→ mark0708: 可是resize都已经加上ref 进行操作了... 02/08 14:53
14F:推 Litfal: 跟 var 没关系, 它只是语法糖 02/08 15:42
15F:推 Litfal: 原因在於你的var代表的是一个structure,LoadData和varTem 02/08 15:48
16F:→ Litfal: p也是个structure 02/08 15:48
17F:→ Litfal: 所以你的varTemp = LoadData 也是值复制,而不是址复制 02/08 15:49
18F:→ mark0708: 可是这没办法解释 当中的子结构在varTemp resize时 load 02/09 15:26
19F:→ mark0708: 也跟着被改变的情况 02/09 15:27
20F:→ Litfal: 你是说LoadData.metadat[ ] 吗? 02/10 19:47
21F:推 s4300026: 老实说我以为所有的行为都是shallow copy, 所谓的deep c 02/11 19:32
22F:→ s4300026: opy要自己写... 02/11 19:32
23F:→ s4300026: 原po你可以把两种的操作情境的变数名称写完整一点吗? 02/11 19:34
24F:推 s4300026: point a,b; a.x=3; b=a; b.x=10; a.x=? 02/11 19:39
25F:推 s4300026: 所以重点在於 a,b 是两个实体,还是一个实体。如果是cla 02/11 19:41
26F:→ s4300026: ss则为一,struct则为2。 02/11 19:41
27F:推 s4300026: 会null的原因是因为你是走struct copy, 也就是值复制, 02/11 19:50
28F:→ s4300026: 等号左边的接收者会多产生一个物件, 而不会null 的原 02/11 19:50
29F:→ s4300026: 因是因为走class copy, 等号左边的接收者只拿到参考的 02/11 19:50
30F:→ s4300026: 复制品, 因此并没有多复制一个物件出来。 然後你都只有 02/11 19:50
31F:→ s4300026: 传入左侧的复制者,然後去看右边的人有没有改变,如果是 02/11 19:50
32F:→ s4300026: 值复制,就不会同步,如果是参考复制,就会同步。 02/11 19:50
33F:推 s4300026: 第一次你做struct的=, 因此没同步。第二次你做array的=, 02/11 19:53
34F:→ s4300026: array的=是class copy, 因此有同步。 02/11 19:53
35F:推 Litfal: 建议原po用 object.ReferenceEquals 去比对一下就会理解 02/11 20:26