本篇体验引用类型转换:子类转换成父类,父类转换成子类,以及不是子父级关系类之间的转换。

□ 隐式转换:子类转换成父类

    public class Animal
    {
        public int _age;
        public Animal(int age)
        {
            this._age = age;
        }
    }
    public class Dog : Animal
    {
        public float _weight;
        public Dog(float weight, int age) : base(age)
        {
            _weight = weight;
        }
    }

客户端,子类转换成父类。

        static void Main(string[] args)
        {
            Dog dog = new Dog(2.5f,12);
            Animal animal = dog;
            Console.WriteLine(animal._age);
        }

结果:12

可见,子类转换成了父类是隐式转换。这种转换在栈上完成,栈上先有代表子类的变量dog,然后有代表父类的变量animal,最后把dog保存的堆地址赋值给了anmial。

□ 强转:父类转换成子类

如果客户端父类转换成子类。

        static void Main(string[] args)
        {
            Animal animal = new Animal(12);
            Dog dog = (Dog)animal;
            Dog dog = animal as Dog;
            if (dog != null)
            {
                Console.WriteLine(dog._age);
            }
            else
            {
                Console.WriteLine("转换失败");
            }
        }

结果:抛出异常,Animal无法转换成Dog

可见,使用以上方式把父类强转成子类,转换失败会抛出异常。

□ 使用as强转:父类转换成子类

如果客户端使用as把父类转换成子类。

        static void Main(string[] args)
        {
            Animal animal = new Animal(12);
            Dog dog = animal as Dog;
            if (dog != null)
            {
                Console.WriteLine(dog._age);
            }
            else
            {
                Console.WriteLine("转换失败");
            }
        }

结果:转换失败

可见,使用as把父类强转成子类,转换失败不会抛出异常。

□ 使用is先判断再强转:父类转换成子类

可以在强转之前,先使用is判断父类是否能转换成子类,再根据子类实例是否为null判断是否转换成功。

        static void Main(string[] args)
        {
            Animal animal = new Animal(12);
            Dog dog = null;
            if (animal is Dog)
            {
                dog = (Dog)animal;
            }
            if (dog == null)
            {
                Console.WriteLine("转换失败");
            }
            else
            {
                Console.WriteLine("转换成功");
            }
        }

□ 使用操作符实现强转

可以在一个类中设计一个静态的、隐式的、操作符方法,把本类实例转换成另外一个目标转换对象实例。

    public class Benz
    {
        public int Mile { get; set; }
        public Benz(int mile)
        {
            Mile = mile;
        }
        public static implicit operator Car(Benz benz)
        {
            return new Car(){Mile = benz.Mile};
        }
    }
    public class Car
    {
        public int Mile { get; set; }
    }

客户端

        static void Main(string[] args)
        {
            Benz benz = new Benz(1000);
            Car car = benz;
            Console.WriteLine(car.Mile);
            Console.ReadKey();
        }

结果:1000

○ 使用操作符,把原本毫无关系的2个类建立关系,可实现转换
○ 当执行Car car = benz的时候,就会执行Benz类的操作符方法operator Car
○ 操作符方法必须满足几个条件:静态的、implicit,名称和需要转换的类名保持一致,返回需要转换的类实例
○ 当执行Car car = benz的时候,在堆上创建一个Car实例,然后赋值给栈上的变量car

总结:
○ 子类转换成父类是隐式转换,其本质是栈上的一个变量值赋值给了栈上另外一个变量
○ 父类转换成子类,如果直接使用"(子类)父类实例"的方式,很容易抛出异常
○ 父类转换成子类,如果使用as,可以避免抛出异常
○ 父类转换成之类,也可以先使用is判断,然后再进行转换
○ 2个不是子父级关系的类,可以在1个类中设计一个操作符方法,把该类实例转换成目标对象实例

转载于:https://www.cnblogs.com/darrenji/p/3975447.html

C#引用类型转换的几种方式相关推荐

  1. PHP中数据类型转换有多少种,PHP中数据类型转换的三种方式

    PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形 2.(float).(double).(real):转换成浮点型 3.(string): ...

  2. Latex引用参考文献的5种方式

    0. 首先确保你编译latex的文件夹中有以下四个文件 elsarticle-harv.bst elsarticle-num.bst elsarticle-num-names.bst mybib.bi ...

  3. 引用JavaScript的三种方式第二课

    语法约定: 1.区分大小写 2.代码缩进 3.建议每行只写一条语句,语句以分号结尾(如果没有分号,软件默认会找到这个行的尾行,如果尾行没有东西,没有其他代码,则默认为结束,如果有代码,可以会报错) 4 ...

  4. java tryparse用法_数据类型转换的三种方式 Convert,parse和TryParse的解析

    以Int类型为例,具体说明Convert.ToInt32(object value),int.Parse(object value)和int.TryParse(string s,out int res ...

  5. java如何做全局缓存_传智播客JNI第七讲 – JNI中的全局引用/局部引用/弱全局引用、缓存jfieldID和jmethodID的两种方式...

    讲解JNI中的全局引用/局部引用/弱全局引用.缓存jfieldID和jmethodID的两种方式,并编写两种缓存方式的示例代码. 1.从Java虚拟机创建的对象传到本地C/C++代码时会产生引用,根据 ...

  6. 获得Class引用的三种方式?Class.forName()、getClass以及.class的使用

    上代码!!! package com.spring.partise;class A{static{System.out.println("I am A");} } public c ...

  7. HTML 引用Css样式的四种方式

    不才,只知道HTML引用CSS样式有四种方式,内部引用和外部引用各两种,因为老是忘记细节,记下了随时翻阅亦可方便如我般的初学者 内部引用方式1: 直接在标签内用 style 引用,如: <div ...

  8. php 递归实现无限极分类和排序_无限极分类的两种方式,递归和引用

    说到无限极分类,比较常见的做法是在建表的时候,增加一个parnet_id字段用来区别自己所属的分类(是顶级分类还是子分类) 由于展示数据的时候,需要表达出这种所属关系,所以必然要在读取数据的时候进行一 ...

  9. html中引入css样式表的三种方式,css引用的几种方式是什么?

    HTML怎么引用CSS样式?css引用的几种方式是什么?下面本篇文章就来给大家介绍一下在HTML中引用CSS样式的几种方法,希望对大家有所帮助. 1.行内式 在HTML标签中,使用style属性设置C ...

最新文章

  1. 反正我不信!马斯克谈元宇宙:没人愿意把屏幕贴脸上
  2. ie8开发人员工具无法使用,按f12任务栏里出现任务,但是窗体不弹出
  3. 惊闻VeryCD的电驴下载部分即将关闭
  4. 1.16 Java的异常跟踪栈
  5. UWP 剪贴板 Clipboard
  6. Java异常处理和常用类
  7. The content of element type web-app must match……等 问题之解决办法
  8. rust: 写CTP策略中的几个难点
  9. php万能表单制作教程,万能表单系统
  10. php 真太阳时间修正,真太阳时查询表(建议收藏)
  11. 关于PCB与设备外壳接地问题
  12. html5 csss透明,详解CSS透明opacity和IE各版本透明度滤镜filter的最准确用法
  13. 第四章 姜诸儿意气风发登君位 鲁桓公窝囊枉死彭生手
  14. 最新文本转语音的接口(免费),百度语音作废
  15. USB接口EMC设计方案
  16. 录屏时如何录制麦克风声音?-QVE屏幕录制
  17. Linux系统磁盘高级应用适合初学者
  18. ActiveMQ消费者断开重连
  19. application实现一个简单的网页计数器
  20. JavaPoet使用攻略

热门文章

  1. linux deepin安装virtualbox 6.1命令
  2. K8S删除某一个命名空间下所有的pod deployment statefulset命令
  3. Azkaban与Oozie的区别及如何调度spark任务
  4. golang设置运行CPU数量及sync.Mutex全局互斥锁的使用示例
  5. nginx反向代理tomcat
  6. Apollo配置灰度发布
  7. 多级缓存中的一级缓存全网流量分发CDN
  8. hadoop分布式文件系统hdfs的概念和特性
  9. Hibernate注解开发-PO类注解配置
  10. 信息系统服务器备机,医院信息系统业务连续性讨论:双机热备、RAC还是x86一体机?...