加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 上传/下传和序列化

发布时间:2020-12-16 01:57:23 所属栏目:百科 来源:网络整理
导读:只是玩弄铸造.假设我们有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仍然保持字段
只是玩弄铸造.假设我们有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字段吗?

解决方法

Actually,the question is about what happens in memory

所以;那不是序列化. 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,所以这里没有任何问题.最后,我们得到了问题(来自评论(:

Then,another question (more detailed): how Inh would be stored in array of Bases? Would b be just dropped?

绝对不.因为它们是引用类型,所以列表实际上不包含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
> obj as Foo – 执行类型测试,返回类型为Foo的引用,如果它是非null并且是匹配的,否则返回null
>(Foo)obj – 执行类型测试,如果为null则返回null,如果是匹配则引用类型为Foo,否则抛出异常

所以这个循环也可以写成:

int sum = 0;
foreach (var item in list)
{
    sum += item.a;
    Inh inh = item as Inh;
    if(inh != null)
    {
       Console.WriteLine(inh.b);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读