美文网首页
c# dynamic、var、object的区别

c# dynamic、var、object的区别

作者: _sands | 来源:发表于2019-08-22 18:41 被阅读0次

    dynamic、var、object 这三个是c# 代码中常用的关键字,其中的区别和联系不搞明白的话确实容易混淆

    object

    支持 .NET 类层次结构中的所有类,并为派生类提供低级别服务。 这是所有 .NET 类的最终基类;它是类型层次结构的根。
    通常类都是隐式继承Object。
    object类型和其他值类型之间的转换称之为装箱和拆箱操作,
    装箱:将值类型转换成引用类型,
    拆箱:将引用类型转换成值类型。
    装箱和取消装箱类型的过程会带来额外的性能开销。所以实际开发中应该多使用泛型来规避装箱拆箱操作。

    装箱示例:

    [TestClass]
        public class DynamicUnitTest
        {
            [TestMethod]
            public void Convert()
            {
                int a = 100;
                object to = a;
            }
        }
    
    看下 IL代码
    
    IL_0000: nop
    IL_0001: ldc.i4.s 100
    IL_0003: stloc.0
    IL_0004: ldloc.0
    IL_0005: box [System.Runtime]System.Int32    //这里的box就是装箱操作
    IL_000a: stloc.1
    IL_000b: ret
    

    拆箱示例

     [TestClass]
        public class DynamicUnitTest
        {
            [TestMethod]
            public void Convert()
            {
                object a = 100;
                int to = (int)a;
            }
        }
    
    看下IL代码
    
    IL_0000: nop
    IL_0001: ldc.i4.s 100
    //先执行装箱操作 目的是为了将数字1 int转换为object
    IL_0003: box [System.Runtime]System.Int32  
    IL_0008: stloc.0
    IL_0009: ldloc.0
    //执行拆箱操作 目的是将object转换成int
    IL_000a: unbox.any [System.Runtime]System.Int32 
    IL_000f: stloc.1
    IL_0010: ret
    

    如果将变量a的赋值改为string类型的
    object a = "100";
    string to = (string)a;
    再看看IL代码

    IL_0000: nop
    IL_0001: ldstr "100"
    IL_0006: stloc.0
    IL_0007: ldloc.0
    //这里没有装箱和拆箱操作 只有castclass 类型转换操作 因为string也是引用类型,而不是值类型
    IL_0008: castclass [System.Runtime]System.String 
    IL_000d: stloc.1
    IL_000e: ret
    

    再看看 var
    var 和 js中的var作用是一样的,定义一个变量的类型,不需要明确定义类型是什么,编译器在源码编译期间根据变量的赋值自己识别类型,并直接改写替换成实际需要的类型;其本质就是个语法糖。
    比如
    var a = 100;
    看IL代码

    .maxstack 1
    .locals init (
        [0] int32 a
    )
    
    IL_0000: nop
    IL_0001: ldc.i4.s 100
    IL_0003: stloc.0
    IL_0004: ldloc.0
    

    locals 定义的类型直接就是 int型

    dynamic

    编程语言划分为静态类型语言和动态类型语言。C#和Java经常被认为是静态类型的语言,而Python、JavaScript是动态类型语言。一般动态语言在编译时不会对类型进行检查,编写随意,而是在运行时识别对象的类型。而静态语言,在编写时就对类型进行了严格的检查。
    dynamic是FrameWork4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性,但是他在IL中的类型到底是什么,是怎么实现这些特性的?
    比如
    dynamic a = 100;
    int s = a + 1;
    看下IL代码

    .locals init (
        [0] object a,   //dynamic直接就换成了object
        [1] int32 s
    )
    
    // (no C# code)
    IL_0000: nop
    // dynamic val = 100;
    IL_0001: ldc.i4.s 100
    IL_0003: box [System.Runtime]System.Int32  //object类型的变量a 的赋值是值类型的,所以产生了装箱操作
    IL_0008: stloc.0
    

    由此可以看出dynamic本质上就是个object类型,只不过在写源代码的时候不再进行类型检查,从而减少了类型转换的操作,实现了动态语言的特征。

    所以总结下来
    用var请随意 ,符合代码规范即可;
    object和dynamic使用的时候 要注意装箱和拆箱操作,尽量使用泛型规避;

    相关文章

      网友评论

          本文标题:c# dynamic、var、object的区别

          本文链接:https://www.haomeiwen.com/subject/pnrosctx.html