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#引用类型转换,到底使用is,as还是显式强转?的更多相关文章
- Java引用类型转换
java的引用类型转换分为两种: 向上类型转换,是小类型到大类型的转换 向下类型转换,是大类型到小类型的转换 现存在一个Animal动物类,猫子类和狗子类继承于Animal父类: 1 public c ...
- C#引用类型转换的几种方式
本篇体验引用类型转换:子类转换成父类,父类转换成子类,以及不是子父级关系类之间的转换. □ 隐式转换:子类转换成父类 public class Animal { public int _age; pu ...
- Java学习笔记二十六:Java多态中的引用类型转换
Java多态中的引用类型转换 引用类型转换: 1.向上类型转换(隐式/自动类型转换),是小类型到大类型的转换: 2.向下类型转换(强制类型转换),是大类型到小类型的转换: 3.instanceof运算 ...
- Day06_28_Instanceof关键字 和 引用类型转换
Instanceof关键字 和 引用类型转换 Instanceof 关键字 - instanceof 是 Java 的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean ...
- C++进阶--显式类型转换(casting)
//############################################################################ /* * 显式类型转换 * * 类型转换 ...
- C++显式类型转换
C++显式类型转换 (注:本文例程改编自<C++ Primer>) 关于类型转换,C++保留了C语言中的类型转换方式,并提供了4中新的类型转换方式.<Effective C++> ...
- c# implicit explicit关键字(隐式和显式数据类型转换)
implicit关键字用于声明隐式的用户定义类型转换运算符.(explicit反之)explicit则用于显示转换用户自定义类型.static implicit operator target_typ ...
- JavaScript 数据类型转换(显式与隐式)
一.数据类型 JS中有5中简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number.String.还有一种复杂数据类型------Object,Object本质是 ...
- Golang 类型转换,断言和显式强制转换
1 前言 类型转换,可以用断言(只能使用在interface{}类型转换成其它类型)和显式类型强制转换(常规是用于基本类型) 2 代码 //graphql-go func(params graphql ...
随机推荐
- 课堂实验-模拟实现Sort
课堂实验 模拟实现Linux下Sort -t : -k 2的功能.参考 Sort的实现. 代码如下: /** * Created by Administrator on 2017/5/20. */ i ...
- [C++]返回最值元素
1 priority_queue C++中优先队列是一种特殊的队列,能够返回队列中优先级最大或者最小的元素,其内部是由堆实现的,个人认为这种方式使用更加直观. 1.1 返回vector中的最值元素 # ...
- 20165333实验一 JAVA开发环境的熟悉
JAVA开发环境的熟悉-1 1建立"自己学号exp1"的目录 2 在"自己学号exp1"目录下建立src,bin等目录 3 javac,java的执行在&quo ...
- Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件
前言: 忙完了结婚乐APP的开发,终于可以花一定的时间放在博客上了.好了,废话不多说,今天我们要带来的效果是苹果版本的QQ下拉刷新.首先看一下目标效果以及demo效果: 因为此效果实现的步骤 ...
- 12 打印1到最大的n位数
输入数字 n,按顺序打印出从 1 最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数即 999.由于 n 可能会非常大,因此不能直接用 int 表示数字,而是用 cha ...
- Web前端开发最佳实践(12):JavaScript代码中有大量写死的配置数据?这些数据难以维护,你需要合理组织这些数据
前言 JavaScript代码基本上都是由业务逻辑和数据组成的,逻辑代码根据数据完成一定的操作.很多数据在代码中是写死的,比如一些URL.显示在界面上的提示信息.页面元素相关的样式值及其他使用到的固定 ...
- LoadRunner WebTours无法显示页面
- OpenJudge——0003:jubeeeeeat
OpenJudge——0003:jubeeeeeat 描述 众所周知,LZF很喜欢打一个叫Jubeat的游戏.这是个音乐游戏,游戏界面是4×4的方阵,会根据音乐节奏要求玩家按下一些指定方块(以下称co ...
- event使用说明和DHTML参数属性
event 对象 代表事件状态,如事件发生的元素,键盘状态,鼠标位置和鼠标按钮状态. DHTML元素属性列表 属性 描述 abstract 使用 event 对象获取高级流重定向器(ASX)文件中项目 ...
- 【WIN10】判斷程序運行在哪個平台
其中的一個方法是: string x = AnalyticsInfo.VersionInfo.DeviceFamily; 判斷 x 的值,有”Windows.Mobile“,”Windows.Des ...