c# – 上传/下传和序列化
只是玩弄铸造.假设我们有2个班级
public class Base { public int a; } public class Inh : Base { public int b; } 实例化它们 Base b1 = new Base {a = 1}; Inh i1 = new Inh {a = 2,b = 2}; 现在,让我们试试upcast // Upcast Base b2 = i1; 似乎b2仍然保持字段b,仅在Inh类中呈现.让我们通过向下转发来检查它. // Downcast var b3 = b2; var i2 = b2 as Inh; var i3 = b3 as Inh; bool check = (i2 == i3); 检查在这里是真的(我猜,因为i2和i3引用相同的实例i1). var list = new List<Base>(); list.Add(new Base {a = 5}); list.Add(new Inh {a = 10,b = 5}); int sum = 0; foreach (var item in list) { sum += item.a; } 一切都没问题,因为总和是15.但是当我尝试使用XmlSerializer序列化数组时(只是看看里面是什么),它返回InvalidOperationException“类型ConsoleApplication1.Inh不是预期的”.嗯,公平,因为它的阵列. 那么,实际上b2是什么?我可以序列化一系列Bases和Inhs吗?我可以通过从反序列化数组中转发项目来获取Inhs字段吗? 解决方法
所以;那不是序列化. K. 让我们从顶部开始,然后: public class Base { public int a; } public class Inh : Base { public int b; } 这里我们有两个引用类型(类);它们是引用类型的事实非常重要,因为它直接影响实际存储在数组/变量中的内容. Base b1 = new Base {a = 1}; Inh i1 = new Inh {a = 2,b = 2}; 在这里我们创建2个对象;类型为Base之一,类型为Inh之一.对每个对象的引用分别存储在b1 / i1中.我将字引用用斜体显示有一个原因:它不是那里的对象.该对象在托管堆上是任意的.基本上b1和i1只是将内存地址保存到实际对象.旁注:“引用”,“地址”和“指针”之间存在细微的技术差异,但它们在此处起着相同的作用. Base b2 = i1; 这将复制引用,并将该引用分配给b2.请注意,我们还没有复制该对象.我们仍然只有2个对象.我们复制的只是代表内存地址的数字. var b3 = b2; var i2 = b2 as Inh; var i3 = b3 as Inh; bool check = (i2 == i3); 在这里,我们反过来做同样的事情. var list = new List<Base>(); list.Add(new Base {a = 5}); list.Add(new Inh {a = 10,b = 5}); int sum = 0; foreach (var item in list) { sum += item.a; } 这里的列表是参考列表.托管堆上的对象仍然是任意的.所以,是的,我们可以遍历它们.因为所有的Inh也是Base,所以这里没有任何问题.最后,我们得到了问题(来自评论(:
绝对不.因为它们是引用类型,所以列表实际上不包含Inh或Base对象 – 它只包含引用.该引用只是一个数字 – 例如120934813940.一个内存地址,基本上.我们是否认为120934813940指向Base或Inh并不重要 – 我们在任何一个术语中谈论它都不会影响位于120934813940的实际对象.我们需要做的就是执行强制转换,这意味着:不要将120934813940视为基础,而是将其视为一个Inh – 它涉及一种类型测试,以确认它是我们怀疑的.例如: int sum = 0; foreach (var item in list) { sum += item.a; if(item is Inh) { Inh inh = (Inh)item; Console.WriteLine(inh.b); } } 所以b一直都在那里!我们无法看到它的唯一原因是我们只假设该项目是基础.要访问b,我们需要转换值.这里有三个常用的重要操作: > obj is Foo – 执行类型测试,如果该值为非null,则返回true,并且可以简单地指定为该类型,否则为false 所以这个循环也可以写成: int sum = 0; foreach (var item in list) { sum += item.a; Inh inh = item as Inh; if(inh != null) { Console.WriteLine(inh.b); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |