• .NET 值类型 引用类型


    注意:被装过箱的对象才能被拆箱
    拆箱必须非常小心,确保该值变量有足够的空间存储拆箱后得到的值。C#int只有32位,如果把64位的long值
    拆箱为int时,会产生一个InvalidCastExecption异常。
    显然,从原理上可以看出,装箱时,生成的是全新的引用对象,这会有时间损耗,也就是造成效率降低。装箱操作
    和拆箱操作是要额外耗费cpu和内存资源的,所以在c# 2.0之后引入了泛型[泛型不存在boxing、unboxing,类型是安全的]来减少装箱操作和拆箱操作消耗。

    值类型和引用类型

    值类型:整型、浮点型、布尔型、枚举型、结构体等
    引用类型:类、string、接口、数组、委托等
    所有的值类型都是密封(seal)的。所以无法派生出新的值类型
    值得注意的是,引用类型和值类型都是继承自System.Object类。不同的是,几乎所有的引用的类型都直接从Sytem.Object继承,
    而值类型则继承其子类,即直接继承System.ValueType
    System.ValueType直接派生于System.Object,即Sytem.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较。
    可以用Type.IsValueType属性来判断一个类型是否为值类型。
    AAAA aa=new AAAA()
    aa.GetType().IsValueType

    string str = “str”;
    int int_s = 50;
    MessageBox.Show(str.GetType().IsValueType.ToString());
    MessageBox.Show(int_s.GetType().IsValueType.ToString());

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    当我们要比较两个值类型【ValueType】变量是否相等式,可以调用继承自ValueType类型的Equals()方法。
    这个复写的方法内部使用了反射,获得值类型所有字段,然后进行比较。

    C#值类型,我们可以把他归纳成三类:
    第一类: 基础数据类型(string类型除外):包括整型、浮点型、十进制型、布尔型。
    整型包括:sbyte、byte、char、short、ushort、int、uint、long、ulong 这九种类型;
    浮点型就包括 float 和 double 两种类型;
    十进制型就是 decimal ;
    布尔型就是 bool 型了。
    第二类:结构类型:就是 struct 型
    第三类:枚举类型:就是 enum 型

    C#引用类型有五种:class、interface、delegate、object、string、Array。
    所有值类型的数据都无法为null的(除可空类型修饰 int ?xx=null),声明后必须赋以初值;引用类型才允许为null。

    可空类型
    可空类型可以表示基础类型的所有值,另外还可以表示 null 值。
    可空类型可通过下面两种方式中的一种声明:
    System.Nullable variable
    T? variable
    T 是可空类型的基础类型。T 可以是包括 struct 在内的任何值类型;但不能是引用类型。
    1.值类型后加问号表示此类型为可空类型,如int? i = null;
    int? d = null;
    System.Nullable e = null;
    2.可空类型与一元或二元运算符一起使用时,只要有一个操作数为null,结果都为null;
    在这里插入图片描述
    3.比较可空类型时,只要一个操作数为null,比较结果就为false。
    在这里插入图片描述
    对于C#中的参数传递,根据参数的类型可以分为四类:
    值类型参数的按值传递
    引用类型参数的按值传递
    值类型参数的按引用传递
    引用类型参数的按引用传递
    引用类型参数的按值传递
    当传递的参数是引用类型的时候,传递和操作的是指向对象的引用(看到这里,有些朋友会觉得此时不是传递引用吗?怎
    么还是按值传递了?对于这个疑惑,此时确实是按值传递,此时传递的对象的地址,传递地址本身也是传递这个地址的
    值,所以此时仍然是按值传递的),此时方法的操作就会改变原来的对象。
    class Program
    {
    static void Main(string[] args)
    {
    // 2. 引用类型按值传递情况
    RefClass refClass = new RefClass();
    AddRef(refClass);
    Console.WriteLine(refClass.addnum);
    }
    // 2. 引用类型按值传递情况
    private static void AddRef(RefClass addnumRef)
    {
    addnumRef.addnum += 1;
    Console.WriteLine(addnumRef.addnum);
    }
    }
    class RefClass
    {
    public int addnum=1;
    }

    // 上面结果都是2
    String引用类型的按值传递的特殊情况
    class Program
    {
    static void Main(string[] args)
    {
    // 3. String引用类型的按值传递的特殊情况
    string str = “old string”;
    ChangeStr(str);
    Console.WriteLine(str);

    }

    // 3. String引用类型的按值传递的特殊情况
    private static void ChangeStr(string oldStr)
    {
    oldStr = “New string”;
    Console.WriteLine(oldStr);
    }
    }
    在这里插入图片描述

    按引用传递

    不管是值类型还是引用类型,我们都可以使用ref 或out关键字来实现参数的按引用传递,然而按引用进行传递的时候,需
    要注意下面两点:
    方法的定义和方法调用都必须同时显式使用ref或out,否则会出现编译错误

    CLR 允许out或ref参数来实现方法重载
    #region CLR 允许out或ref参数来实现方法重载
    private static void Add(string str)
    {
    Console.WriteLine(str);
    }
    // 编译器会认为下面的方法是另一个方法,从而实现方法重载
    private static void Add(ref string str)
    {
    Console.WriteLine(str);
    }
    #endregion

    class Program
    {
    static void Main(string[] args)
    {
    #region 按引用传递
    Console.WriteLine(“按引用传递的情况”);
    int num = 1;
    string refStr = “Old string”;
    ChangeByValue(ref num);
    Console.WriteLine(num);
    changeByRef(ref refStr);
    Console.WriteLine(refStr);
    #endregion
    Console.Read();
    }
    #region 按引用传递
    // 1. 值类型的按引用传递情况
    private static void ChangeByValue(ref int numValue)
    {
    numValue = 10;
    Console.WriteLine(numValue);
    }
    // 2. 引用类型的按引用传递情况
    private static void changeByRef(ref string numRef)
    {
    numRef = “new string”;
    Console.WriteLine(numRef);
    }
    #endregion
    }

    在这里插入图片描述
    对于按值传递,不管是值类型还是引用类型的按值传递,都是传递实参的
    一个拷贝,只是值类型时,此时传递的是实参实例的一个拷贝(也就是值类型值的一个拷贝),而引用类型时,此时传递
    的实参引用的副本。对于按引用传递,传递的都是参数地址,也就是实例的指针。

  • 相关阅读:
    【全民编程】《软件编程-讲课视频》【零基础入门到实战应用】
    ssm+vue租房维保系统-房屋维修系统
    高效+灵活+安全=低代码的三位一体解决方案
    08:STM32----DMA数据转运
    LC-813 最大平均值和的分组(动态规划(背包问题变形))
    【无标题】
    航天联志Aisino-AISINO26081R服务器通过调BIOS用U盘重新做系统(windows系统通用)
    微信还有哪些你不知道的神奇能力?
    net-java-php-python-汽车租赁系统计算机毕业设计程序
    【递归、搜索与回溯算法】第五节.129. 求根节点到叶节点数字之和和814. 二叉树剪枝
  • 原文地址:https://blog.csdn.net/u013400314/article/details/126579937