C#   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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
> 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);
    }
}

大佬总结

以上是大佬教程为你收集整理的c# – 上传/下传和序列化全部内容,希望文章能够帮你解决c# – 上传/下传和序列化所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。