• 关于C#从⼀个List复制到另⼀个List的简便写法。


    关于C#从⼀个List复制到另⼀个List的简便写法。
    我们都知道,C#的变量在类型上可以分为值类型和引⽤类型。
    所谓值类型就是这个变量存储的是⼀个具体的值,两个值类型的值是相互独⽴的,修改⼀个不会影响另⼀个。例如:
    int i = 1;int j = i;
    i++;
    Console.WriteLine(i + " " + j); // 输出 2 1
    引⽤类型则类似C++的指针,变量⾥⾯存放的是具体的内存地址,修改⼀个会影响另⼀个。例如:
    public class EXPoint3d
    {
    public int x;
    public int y;
    public EXPoint3d(int x, int y)
    {
    this.x = x;this.y = y;
    }
    public EXPoint3d(EXPoint3d point)
    {
    this.x = point.x; this.y = point.y;
    }
    }
    EXPoint3d str1 = new EXPoint3d(11,22), str2 = str1;
    str1.x++;
    Console.WriteLine(str2.x + " " +str2.y);
    List是C#中⼀个很好⽤的⾼效的存储容器,我们也经常会碰到要将⼀个list中的内容复制到另⼀个的需求。
    这时候就要注意了,如果List中存放的是引⽤类型的数据,例如我们⾃⼰定义的class,那么如果直接使⽤常规赋值⽅法复制的话。复制出
    来的list实际上是原list的⼀个拷贝,例如:
    List<EXPoint3d> list1 = new List<EXPoint3d>(); // 原始list
    list1.Add(new EXPoint3d(1, 1));
    list1.Add(new EXPoint3d(2, 2));
    list1.Add(new EXPoint3d(3, 3));
    List<EXPoint3d> list2 = new List<EXPoint3d>();
    foreach (EXPoint3d point in list1) // 第⼀种复制⽅法
    list2.Add(point);
    List<EXPoint3d> list3 = new List<EXPoint3d>(list1); // 第⼆种复制⽅法
    List<EXPoint3d> list4 = list1.ToList(); // 第三种复制⽅法
    list1[0].x += 2;
    Console.WriteLine(list1[0].x + " " + list1[0].y); // 输出 3 1
    Console.WriteLine(list2[0].x + " " + list2[0].y); // 输出 3 1
    Console.WriteLine(list3[0].x + " " + list3[0].y); // 输出 3 1
    Console.WriteLine(list4[0].x + " " + list4[0].y); // 输出 3 1
    上⾯的三种常规复制⽅法,所复制的都只是原有list的浅拷贝也就是引⽤,修改源list⼀定会导致复制的list也会发⽣相应变动。
    那么如何进⾏深拷贝也就是使得复制出来的list不受源list影响呢?这⾥有⼏种⽅法。
    最常规的⽅法就是使⽤for循环在每次赋值的时候new ⼀下,这样当然⾏,不过这⾥介绍另外的⽅法:
    List<EXPoint3d> list1 = new List<EXPoint3d>(); // 原始list
    list1.Add(new EXPoint3d(1, 1));
    list1.Add(new EXPoint3d(2, 2));
    list1.Add(new EXPoint3d(3, 3));
    List<EXPoint3d> list5 = new List<EXPoint3d>();
    foreach (EXPoint3d point in list1) // 第⼀种复制⽅法
    list5.Add(new EXPoint3d(point.x, point.y));
    List<EXPoint3d> list6 = list1.Select(t => new EXPoint3d(t.x, t.y)).ToList(); // 第⼆种⽅法
    list1[0].x += 2;
    Console.WriteLine(list5[0].x + " " + list5[0].y); // 输出 1 1
    Console.WriteLine(list6[0].x + " " + list6[0].y); // 输出 1 1
    有的时候我们还需要按照⼀定的筛选条件将某个list中的内容复制到另⼀个list。这⾥可以使⽤for循环进⾏逐个判断,也有⼀种简便写法。
    这个简便写法的语法与SQL结构化查询语⾔中的select where条件判断是否的类似,举例:
    List<EXPoint3d> list1 = new List<EXPoint3d>(); // 原始list
    list1.Add(new EXPoint3d(1, 1));
    list1.Add(new EXPoint3d(2, 2));
    list1.Add(new EXPoint3d(3, 3));
    List<EXPoint3d> list7 = (from data in list1 where data.x >= 1 && data.y <= 1 select new EXPoint3d(data.x, data.y)).ToList();
    List<EXPoint3d> list8 = (from data in list1 where data.x >= 1 && data.y <= 1 select data).ToList();
    list1[0].x += 2;
    Console.WriteLine(list7[0].x + " " + list7[0].y); // 输出 1 1
    Console.WriteLine(list8[0].x + " " + list8[0].y); // 输出 3 1
    上⾯的list7和list8都是按照语法条件【x⼤于等于⼀,并且y⼩于等于⼀】筛选出来的list1中的对象,区别在于list7是使⽤了new⽽list8只
    是源list1的引⽤拷贝。
    所以修改list1的值会影响到list8但不会对list7造成影响。

  • 相关阅读:
    AngularJS指令的详解
    Linux(Ubuntu)下如何安装JDK
    Hibernate的三种状态
    JS是按值传递还是按引用传递
    git分支管理
    Hibernate注解映射联合主键的三种主要方式
    Linux下解决用户不能执行sudo的方法
    【GStreamer开发】GStreamer基础教程03——动态pipeline
    【GStreamer开发】GStreamer基础教程02——GStreamer概念
    【GStreamer开发】GStreamer基础教程02——GStreamer概念
  • 原文地址:https://www.cnblogs.com/zhyp/p/16334535.html
Copyright © 2020-2023  润新知