目录

  • c#值类型和引用类型
    • 值类型与引用类型都可以用equals来比较吗?

时间:2019年08月19日

前言

今天去面试,技术主管问我值类型和引用类型有什么区别,面对如此基础的知识只能怪自己没有好好准备以及只顾写代码对一些基础知识其然不知所以然,于是我含含糊糊回答了一番:

  • 值类型
  • 数据类型 int float double datetime等数据类型为值类型。
  • 引用类型
  • 类型 string,array,list,dictionary ,queue等都是引用类型,我们也可以自己用class定义引用类型。
  • 而这些类型最终都继承object类型。

技术主管:

  1. 值类型与引用类型都可以用equals来比较吗?
  2. 如何将一个数组a的值赋予数组b然后对b做修改而不影响原来的数组?

以上问题也就是技术主管平时遇到的坑吧。上述的我就不献丑了,所以也是含糊其辞直接回答。所以在面试完了以后我专门针对性的上网查了资料,以下是我的总结,若有错误望博友多多指正^_^。

c#值类型和引用类型

  • 类型
  • 值类型
    • 内置类型:
    • 用户自定义类型:(struct)
    • 枚举:(enum)
  • 引用类型
    • 内置引用类型:
    • 类(class)
      • 委托
      • 装箱值类型
    • 数组
    • 接口类型(interface)
    • void
    • var

基类(共同点)

c#所有类型均继承system.object

值类型继承基类(不同点)

值类型->valuetype->object

应用类型继承

引用类型不会继承valuetype。引用类型可以继承其他类型

技术经理的问题

值类型与引用类型都可以用equals来比较吗?

在object中equal的方法,可以辨别两个对象是否是一个对象的方法。
**注意,上面这句话很关键 必须是一个对象并且值一样**

引用类型以及值类型使用obejct进行数据比较

public class test1
{
    public string name { get; set;}
    public int age { get; set; }
}
static void main(string[] args)
{
    test1 ts1 = new test1();
    ts1.name = "lele";
    ts1.age = 10;
    test1 ts2 = new test1();
    ts2.name = "lele";
    ts2.age = 10;
    bool iszlx= ts1.name.equals(ts2.name);//值类型比较返回 true
    bool isyylx = ts1.equals(ts2); //引用返回 false
}

通过以上的代码测试得出结论值类型是比较两个对象是否是相同内存地址

如何将一个数组a的值赋予数组b然后对b做修改而不影响原来的数组?

刚开始回答比较简单粗暴上代码:

static void main(string[] args)
{
    int[] a = { 1, 2 };
    int[] b = a; \\输出: a={1,2}  ,  b={1,2};
    b[0] = 2; \\这时我做了修改 输出: a={2,2} ,b={2,2}
}

总结

以上可以看到不是我期望的那样不影响原数组a 坑!
总结:原来数组为引用类型,直接赋值等于是将每个元素的地址复制

  1. 如果是引用传递,可以直接将数组变量通过’=’赋值
  2. 如果是值传递的话,那么可以使用 array.copy() 方法或者是buffer.blockcopy(),也可以通过数组变量.clone()或者是copy()方法
 static void main(string[] args)
 {
     int[] i = { 1, 2 };
     int[] b = (int[])i.clone();\\输出: a={1,2}  ,  b={1,2};
     b[0] = 2;\\输出: a={1,2}  ,  b={2,2};
 }

符合预期.

总结一些东西:

  1. 值类型与引用类型最终都继承最终都继承system.object但值类型中间继承system.valuetype。
    2。 对于引用类型以及值类型一定要分清,不然编程过程中容易出bug