C#使用is、as关键字以及显式强转实现引用类型转换

在C#中,当引用类型需要转换的时候,经常会用到关键字is、as以及显式强转。本篇来体验这三者的用法。

先来梳理.NET引用类型转换的"约定俗成",或者叫"惯例":

  • 子类可以隐式转换为父类/基类,也就是"里氏替换原则"所说的:子类必须能够替换其父类/基类。
  • 父类/基类转换为子类时,必须进行显式类型强转。

子类转换成父类

    class Program
    {
        static void Main(string[] args)
        {
            Animal animal = new Dog(){Name = "Dog",Age = 1};
            Console.WriteLine(animal.Name);
            Console.ReadKey();
        }
    }

    public class Animal
    {
        public string Name { get; set; }
    }

    public class Dog : Animal
    {
        public int Age { get; set; }
    }

输出结果:Dog

以上,体验了子类转换成父类,从中可以看出:子类Dog确实能替换父类Animal,换句话说,子类就是父类,子类的实例可以赋值给父类的变量,不需要as,不需要强转,一切都是隐式发生,很好地体现了"里氏替换原则"。

父类转换为子类,父类变量通过子类赋值而创建

父类as成子类:

Animal animal = new Dog(){Name = "Dog",Age = 1};
Dog dog = animal as Dog;
Console.WriteLine(dog.Name + " " + dog.Age);
Console.ReadKey();

输出结果:Dog 1

父类显式强转成子类

Animal animal = new Dog(){Name = "Dog",Age = 1};
Dog dog = (Dog)animal;
Console.WriteLine(dog.Name + " " + dog.Age);
Console.ReadKey();

输出结果:Dog 1

以上,不管是使用as还是显式强转,父类都可以转换成子类,但是有前提的:把子类实例赋值给父类变量。

父类转换为子类,父类变量通过自身构造函数而创建

父类as成子类失败:

Animal animal = new Animal(){Name = "Sheep"};
Dog dog = animal as Dog;
Console.WriteLine(dog.Name + " " + dog.Age);
Console.ReadKey();

输出结果:报"NullReferenceException"错

可见,当父类变量通过自身构造函数而创建时,无法将父类转换成子类。

(1)为了避免as的时候报"NullReferenceException"错,引入关键is做类型判断:

Animal animal = new Animal(){Name = "Sheep"};
if (animal is Dog)
{
    Dog dog = animal as Dog;
    Console.WriteLine(dog.Name + " " + dog.Age);
}
else
{
    Console.WriteLine("animal不能转换为Dog");
}
Console.ReadKey();

输出结果:animal不能转换为Dog

(2)用as做类型转换的时候,如果转换失败,返回null。根据这点,也可以通过判断as转换后的返回值是否为null,来避免报错:

Animal animal = new Animal(){Name = "Sheep"};
Dog dog = animal as Dog;
if (dog != null)
{
    Console.WriteLine(dog.Name + " " + dog.Age);
}
else
{
    Console.WriteLine("animal不能转换为Dog");
}
Console.ReadKey();

输出结果:animal不能转换为Dog

父类显式强转成子类失败

Animal animal = new Animal(){Name = "Sheep"};
Dog dog = (Dog) animal;
Console.WriteLine(dog.Name + " " + dog.Age);
Console.ReadKey();

输出结果:报"InvalidCastException"错

可见,当父类变量通过自身构造函数而创建时,无法将父类转换成子类。

为了避免显示强转时报"InvalidCastException"错,引入关键字is做类型判断:

Animal animal = new Animal(){Name = "Sheep"};
if (animal is Dog)
{
    Dog dog = (Dog)animal;
    Console.WriteLine(dog.Name + " " + dog.Age);
}
else
{
    Console.WriteLine("animal不能转换为Dog");
}
Console.ReadKey();

输出结果:animal不能转换为Dog

总结

  • 对于引用类型的转换,应该考虑使用显式强转或as。两者的区别在于:一旦类型无法转换,使用显式强转会报错,而使用as会返回null。
  • 为了避免显式强转或as所引发的报错,应该考虑使用is来判断类型间是否能转换。
  • 使用as进行引用类型转换,不仅可以用is来判断类型间是否能转换,还可以通过判断as后的返回值是否为null,然后采取相应的操作。
  • 对于基本类型的转换:使用Convert, Parse, TryParse等。

is用于判断类型是否一致,as和显式强转用于类型的转换。

到此这篇关于C#实现引用类型转换的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#实现数组元素的数据类型转换方法详解

    目录 一.场景假设 二.解决方案 三.问题延伸 四.数组类的静态转换方法 五.刨根问底 一.场景假设 假设有一串字符串如下所示,字符串中的数字之间已用英文状态下的逗号隔开.要求用此字符串中的数字快速生成int类型的数组,且尽可能使用最少的代码量. string str = "1,2,3,4,5,6,7,8,9"; 二.解决方案 我相信大多数同学在拿到这题的时候,一般都会给出以下的解决方案: public int[] String2IntArray(string str) { var s

  • C#数据类型转换(显式转型、隐式转型、强制转型)

    C# 的类型转换有显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问题的转换方式.由系统自动转换. 不同类型的数据进行操作(加减乘除赋值等等),是需要进行 类型转换 后,才能继续操作.所以需要“类型转换”. 隐式转型 隐式转型容易理解,当两种或多种数据类型进行某种操作时,不需要干预,系统会自动进行隐式转换. 如 int i = 66666; long b = i; /

  • C#处理类型和二进制数据转换并提高程序性能

    目录 C# 原语类型 1,利用 Buffer 优化数组性能 2,BinaryPrimitives 细粒度操作字节数组 提高代码安全性 3,BitConverter.MemoryMarshal 4,Marshal 实践 更高性能 C# 原语类型 按照内存分配来区分,C# 有值类型.引用类型: 按照基础类型类型来分,C# 有 内置类型.通用类型.自定义类型.匿名类型.元组类型.CTS类型(通用类型系统): C# 的基础类型包括: 整型: sbyte, byte, short, ushort, int

  • C#引用类型转换的常见方式总结

    本文以实例形式简单讲述了引用类型转换的几种常见方式,如:子类转换成父类,父类转换成子类,以及不是子父级关系类之间的转换.现分述如下,供大家参考: 一.隐式转换:子类转换成父类 public class Animal { public int _age; public Animal(int age) { this._age = age; } } public class Dog : Animal { public float _weight; public Dog(float weight, in

  • C#类型转换之自定义隐式转换和显式转换

    目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 其他 应用和设计 读音 前言 有时我们会遇到这么一种情况:在json数据里,数组里的数据类型不一致,导致我们不能直接反序列化为目标类型.最终我们只能反序列化为JObject类型,然后通过字符串取值的方式来取出数据. 下面介绍一种新方式:通过自定义隐式转换,把不一样的数据类型反序列化为一样的数据类型. 基础知识 类型转换有2种:隐式转换和显式转换.但是,不管是隐式转换,还是显式转换,都是生成了一个新对象返回的.改变新对象的属性,不会影响老

  • C#中数据类型的转换介绍

    目录 1.parse转换:将string类型转化为其他类型 2.任意类型转化为string类型 3.隐式转换:自动转换-->小范围到大范围自动转换 4.显示转换:强制转换-->由大范围到小范围的强制转换,不过可能会发生精度丢失 5.最后再给一个简单的题目考考大家: 今天学习了一下数据类型的转换,我整理出了一下笔记: 1.parse转换:将string类型转化为其他类型 //数据类型的转换 //即string"18"==> int 18, //1.parse转换:将st

  • 详解c# 强制转换和类型转换

    由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型. 例如,string 无法隐式转换为 int. 因此,在将 i 声明为 int 后,无法将字符串"Hello"分配给它,如以下代码所示: int i; // error CS0029: Cannot implicitly convert type 'string' to 'int' i = "Hello"; 但有时可能需要将值复制到其他类

  • C# 数据类型转换

    目录 前言 相关介绍 一.函数方法 二.类型转换 [1]. 使用Convert转换 [2]. 使用类型名进行转换 总结 前言 在使用Console.Read()或Console.ReadLine()进行输入时,和Python语言的input()类似 两者都是把键盘键入的内容作为string类型返回,所以有些数据需要经过数据类型的转换才能进行计算. 相关介绍 C# System.Convert 类 微软官方C#函数文档 一.函数方法 下面罗列的函数方法不是全部,仅列举一些常用的 double这种有

  • C#预定义的基础类型转换

    一.BitConverter 将预定义的基础类型与字节数据进行互转(Unicode) 1.将值类型转成字节数组(Unicode):BitConverter.GetBytes() byte[] data = BitConverter.GetBytes('哈'); Console.Write(data);//200,84 (两个字节) Console.Write(BitConverter.GetBytes('1'));//49,0 (两个字节) Console.Write(BitConverter.

  • 详解c# 类型转换

    类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型.在 C# 中,类型铸造有两种形式: 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失.例如,从小的整数类型转换为大的整数类型,从派生类转换为基类. 显式类型转换 - 显式类型转换,即强制类型转换.显式转换需要强制转换运算符,而且强制转换会造成数据丢失. 下面的实例显示了一个显式的类型转换: namespace TypeConversionApplication { class Explici

随机推荐