前言

当年写的比较差:https://www.cnblogs.com/aoximin/p/12965408.html,所以特来重新写一遍。

正文

首先为什么会出现is 和 as 呢?

因为是为了有需要检验的地方,如果直接使用显示转换的话,那么可能直接报错了。

namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
object obj = new Student();
var c = (Teacher)obj;
} public class Student
{ } public class Teacher
{
}
}
}

比如这样肯定会报错的, 因为在运行的时候我们来查看一下il语句。

.method private hidebysig static
void Main (
string[] args
) cil managed
{
.custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x20a4
// Header size: 12
// Code size: 15 (0xf)
.maxstack 1
.entrypoint
.locals init (
[0] object obj,
[1] class ConsoleApp4.Program/Teacher c
) IL_0000: nop
IL_0001: newobj instance void ConsoleApp4.Program/Student::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: castclass ConsoleApp4.Program/Teacher
IL_000d: stloc.1
IL_000e: ret
} // end of method Program::Main

会调用castclass 进行转换。

因为castclass 无法找到他们两个的转换方法(编写显示转换或者隐式转换的方法),他们也不是继承关系,所以会抛出异常。

但是也不要以为所以的强制转换就一定要编写啥编写显示转换或者隐式转换的方法或者是啥继承关系,还有一种是编译器行为。

比如说:

long a = 1;
int b = (int)a;

编译出来的代码是:

IL_000d: stloc.1
IL_000e: ldc.i4.1
IL_000f: conv.i8
IL_0010: stloc.2
IL_0011: ldloc.2
IL_0012: conv.i4
IL_0013: stloc.3

这就是编译器的行为了,编译器认为自己可以处理就不报错了,直接截断作为处理了。

好吧,不能走的太远了,回到is 上。

那么is就可以避免一些运行时候的报错,而不需要用try catch 这种不太优雅的方式。

但是呢,is 是无法去检查自己编写的显示转换或隐式转换的方法,请看VAR:

class Program
{
static void Main(string[] args)
{
object obj = new Student();
if (obj is Teacher)
{
var c = (Teacher)obj;
}
} public class Student
{ } public class Teacher
{
}
}

编译出来呢?是下面这样:

.method private hidebysig static
void Main (
string[] args
) cil managed
{
.custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x20a4
// Header size: 12
// Code size: 30 (0x1e)
.maxstack 2
.entrypoint
.locals init (
[0] object obj,
[1] bool,
[2] class ConsoleApp4.Program/Teacher c
) IL_0000: nop
IL_0001: newobj instance void ConsoleApp4.Program/Student::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: isinst ConsoleApp4.Program/Teacher
IL_000d: ldnull
IL_000e: cgt.un
IL_0010: stloc.1
IL_0011: ldloc.1
IL_0012: brfalse.s IL_001d IL_0014: nop
IL_0015: ldloc.0
IL_0016: castclass ConsoleApp4.Program/Teacher
IL_001b: stloc.2
IL_001c: nop IL_001d: ret
} // end of method Program::Main

is 转换为il代码就是isinst

这个只能判断继承关系,所以嘛,这个呢,其实也能理解,如果是自己编写了转换方法,哪里自己不知道还要is呢。

那么为啥会出现as呢?

还是性能问题嘛。

v1:

static void Main(string[] args)
{
object obj = new Student();
if (obj is Teacher)
{
var c = (Teacher)obj;
}
}

v2:

static void Main(string[] args)
{
object obj = new Student();
var c = obj as Teacher;
} public class Student
{ } public class Teacher
{
}

这两者有啥区别呢?道理上运行结果都一致。

但是呢,v2 更优,因为v2检查了一次,而v1检查来了两次。

v2的il代码:

.method private hidebysig static
void Main (
string[] args
) cil managed
{
.custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x20a4
// Header size: 12
// Code size: 15 (0xf)
.maxstack 1
.entrypoint
.locals init (
[0] object obj,
[1] class ConsoleApp4.Program/Teacher c
) IL_0000: nop
IL_0001: newobj instance void ConsoleApp4.Program/Student::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: isinst ConsoleApp4.Program/Teacher
IL_000d: stloc.1
IL_000e: ret
} // end of method Program::Main

这里也是使用了isinst,因为isinst本身就是检测并且赋值,再来看下isinst的功效

as 只是运行了stloc.1,弹出赋值给局部变量,多了一个赋值过程,两者性能都差不多,所以呢,不要觉得as 好像多比 is 多个一个转换啥的,其实调用的是同一个语句。

只是觉得以前写的过于潦草,整理下罢了。操作系统篇马上就要出炉,比较生硬,共128篇,简单整理一下。

c# is 和 as 浅看重制版的更多相关文章

  1. 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)

    http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...

  2. springboot开发浅谈 2021/05/11

    学习了这么久,本人希望有时间能分享一下,这才写下这篇浅谈,谈谈软件,散散心情. 这是本人的博客园账号,欢迎关注,一起学习. 一开始学习springboot,看了好多网站,搜了好多课程.零零落落学了一些 ...

  3. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  4. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  5. 【uwp】浅谈China Daily 中划词翻译的实现

    学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...

  6. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  7. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  8. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  9. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  10. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

随机推荐

  1. echarts的x轴显示不全的解决办法

    echarts的x轴显示不全的解决办法 一.背景 当x轴类目较多时,label显示时会自动间隔显示,也就是会隐藏掉中间的label,如下图: 二.解决办法 通过设置 xAxis.axisLabel.i ...

  2. ASP.NET Core – Razor Syntax

    前言 Full stack 的问题就是经常需要一阵子离开一个环境. 比如我跑去写 Angular 几个月. 回来写 Razor, 肯定是卡卡的. 尤其是一些比较不常用到的语法. 所以有一个很好的笔记就 ...

  3. 使用 Wake Lock API:保持设备唤醒的最佳实践

    在现代 Web 应用中,尤其是涉及视频播放.实时通信.地图导航等长时间运行的任务时,用户常常希望设备不要因为空闲而自动进入睡眠模式或屏幕变暗.为了解决这一问题,Web API 提供了一个名为 Wake ...

  4. java_day3_Scanner,顺序结构,选择结构(if,switch),循环结构(for,while),

    一.Scanner 键盘录入:程序运行过程中,用户可以根据自己的需求输入参与运算的值 实现键盘录入的步骤 1.导包 2.创建键盘录入对象 3.调用方法实现键盘录入 1)输入整数 2)输入字符串 pub ...

  5. C# ASP.NET Core Web API 框架 实现向手机发送验证码短信

    本文章主要是在C# ASP.NET Core Web API框架实现向手机发送验证码短信功能.这里我选择是一个互亿无线短信验证码平台,其实像阿里云,腾讯云上面也可以. 首先我们先去 互亿无线 http ...

  6. 【VMware VCF】使用 VCF Import Tool 将现有 vSphere 环境导入为 VI 域。

    VCF Import Tool 工具使用两种方式来帮助客户将现有的 vSphere 或 vSphere + vSAN 环境转变为 VMware Cloud Foundation 环境,分别是转换(Co ...

  7. 使用dynamic debug帮助调试

    你一定在kernel source code中看过很多pr_debug()/dev_dbg()/print_hex_dump_debug()吧,这些debug语句提供更多的信息帮助我们了解内核运行流程 ...

  8. C#的函数使用 和参数修饰符 out ref params

    // 函数和方法 // 函数好比对象的动作行为 在定义函数的时候,职责(作用/功能)越单一越好 满足高内聚 低耦合的开发思路 // 变量的命名规则 小驼峰 // 函数的命名规则 大驼峰 动词开头 // ...

  9. HarmonyOS NEXT开发之ArkTS自定义组件学习笔记

    在HarmonyOS中,ArkTS提供了创建自定义组件的能力,允许开发者封装和复用UI代码.以下是关于自定义组件的详细介绍,包括创建自定义组件.页面和自定义组件的生命周期.自定义组件的自定义布局.冻结 ...

  10. 在 K8s 中快速部署使用 GitLab 并构建 DevOps 项目

    作者:张海立,KubeSphere 社区 Ambassador.Talented Speaker,社区用户委员会上海站副站长 原文链接:https://kubesphere.com.cn/blogs/ ...