前言

当年写的比较差: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. 中国信通院高质量数字化转型产品及服务全景图发布,合合信息多项AI产品入选

    随着5G.人工智能.大数据等新一代技术的发展,企业在商业竞争中正面临更多不确定性.中国信通院高度关注企业数字化转型中遇到的痛点,发起"铸基计划-高质量数字化转型行动",链接企业数字 ...

  2. ASP.NET Core – MVC vs Razor Page

    前言 早年只有 MVC, Razor Page 是后来才出现的. 一开始其实我很看不起 Razor Page, MVC 能做的东西为什么要搞多一个 Razor Page 来做呢? 但我还是尝试用了起来 ...

  3. 十七,Spring Boot 整合 MyBatis 的详细步骤(两种方式)

    十七,Spring Boot 整合 MyBatis 的详细步骤(两种方式) @ 目录 十七,Spring Boot 整合 MyBatis 的详细步骤(两种方式) 1. Spring Boot 配置 M ...

  4. 使用 Flutter 3.19 更高效地开发

    我们已隆重推出全新的 Flutter 版本--Flutter 3.19.此版本引入了专为 Gemini 设计的新 Dart SDK.一个能让开发者对 Widget 动画实现精细化控制的全新 Widge ...

  5. [29] CSP模拟2

    A.不相邻集合 考虑值域上连续的段,可以发现连续的长度为 \(x\) 的段的贡献必定为 \(\lceil{\frac{x}{2}}\rceil\) 考虑并查集维护值域连续的段的大小,每次询问求出全部连 ...

  6. 《华为云DTSE》期刊免费下载:10个案例读懂云上架构升级策略

    本文分享自华为云社区<<华为云DTSE>期刊第四期赋能云专刊,赋能云场景下DTSE服务各类开发者的案例分享>,作者:HuaweiCloudDeveloper. 把公司的开发者平 ...

  7. LeetCode 1000. Minimum Cost to Merge Stones (区间 DP)

    根据寒神题解 https://leetcode.com/problems/minimum-cost-to-merge-stones/discuss/247567/JavaC%2B%2BPython-D ...

  8. laravel中添加公共函数

    laravel中添加公共函数 1. 在项目中的新建app/Helper/functions.php文件 2.在项目的跟目录找到composer.json 文件,并打开,然后再autoload中添加如下 ...

  9. Android 基于 Choreographer 的渲染机制详解

    本文介绍了 App 开发者不经常接触到但是在 Android Framework 渲染链路中非常重要的一个类 Choreographer.包括 Choreographer 的引入背景.Choreogr ...

  10. 导入员工 excel 批量上传

    1. 安装 包  npm i xlsx   yarn add xlsx  2. 封装一个上传的组件 src/components/UploadExcel/index.vue code : <te ...