C#:如何正确地克隆列表<>;到月

本文关键字:lt gt 到月 列表 正确地 | 更新日期: 2023-09-27 18:19:58

我有两个列表,一个是原件,另一个是原始的副本

    List<Button> buttonList; // this is the original list
    List<Button> copyButtonList;// this is the copy of button list; this use to sort the list

我想根据我在单独的类中编写的自定义插入排序对copyButtonList进行排序

我按照以下方式将原始列表克隆到副本列表并进行排序

        copyButtonList = buttonList.ToList();
        String s = SortEngine.insertionSort(copyButtonList); 
        msgList.Items.Add(s);

我也尝试以下方法

        copyButtonList = new List<Button>(buttonList);

foreach (var b in buttonList) {
            copyButtonList.Add(b);
        }

在那之后,我试着按照打印两个列表

foreach(var b in buttonList){
            msgList.Items.Add(b.Text);
        }
        foreach(var b in copyButtonList){
            msgList.Items.Add(b.Text);
        }

在以上三种情况下,两个列表都进行了排序:(我只想对copyButtonList进行排序,有人能指出我在这里犯的错误吗?

更新:我的插入排序算法低于

 public static String insertionSort(List<Button> button)
    {
        String key;
        int i = 0;
        int j;
        String s = "";
        for (j = 1; j < button.Count; j++)
        {
            key = button.ElementAt(j).Text;
            i = j - 1;
            while (i >= 0 && int.Parse(button.ElementAt(i).Text) > int.Parse(key))
            {
                button.ElementAt(i + 1).Text = button.ElementAt(i).Text;
                i = i - 1;
            }
            button.ElementAt(i + 1).Text = key;
            if (i == -1)
            {
                s=(button.ElementAt(i + 1).Text + " is the starting Item, keep this in before " + button.ElementAt(i + 2).Text);
            }
            else if (i == j - 1)
            {
                s=(button.ElementAt(i + 1).Text + " is the last Item, keep this in after  " + button.ElementAt(i).Text);
            }
            else
            {
                s=(button.ElementAt(i + 1).Text + " is between " + button.ElementAt(i).Text + " and " + button.ElementAt(i + 2).Text);
            }
        }
        if (button.Count == 1)
        {
            s= ("This is the first Item");
        }
        return s;
    }

C#:如何正确地克隆列表<>;到月

实际上拼写的问题并不愚蠢。由于您没有更改按钮,因此不需要进行深度克隆。你的问题可能在其他地方。以下是的示例

public class Customer
{
    public string Name { get; set; }
    public override string ToString()
    {
        return Name; 
    }
}
public class CustomerComparer : IComparer<Customer>
{
    public int Compare(Customer x, Customer y)
    {
        return x.Name.CompareTo(y.Name);
    }
}

void Print()
{
   List<Customer> l1 = new List<Customer>();
   l1.Add(new Customer() {  Name="aa"});
   l1.Add(new Customer() { Name = "cc" });
   l1.Add(new Customer() { Name = "bb" });
   List<Customer> l2 = new List<Customer>(l1);

   l2.Sort(new CustomerComparer());
   foreach (var item in l1)
        Console.WriteLine(item);

   Console.WriteLine();
   foreach (var item in l2)
        Console.WriteLine(item);
   Console.ReadLine();

}

这将打印

aa

cc

bb

然后

aa

bb

cc

更新

您正在更改按钮,因此需要深度复制。使用此项创建新列表

using System.Linq;
copyButtonList = buttonList.Select(ee => new Button() {  Text= ee.Text}).ToList();

我所说的"更改按钮"是指像这样的线条

button.ElementAt(i + 1).Text = key;

您可能有两个列表,但它们都"指向"/具有相同的对象。当您更改列表1中某个按钮的文本时,意味着该对象也在列表2中更改。

您需要了解什么是值类型,什么是引用类型及其差异。这里有一些链接可以帮助你

http://www.albahari.com/valuevsreftypes.aspx

c#中的引用类型和值类型之间有什么区别?

在你的电脑上运行以下控制台应用程序,看看打印的是什么

using System;
public struct Point
{
  public int X;
  public Point(int initialValue) { X = initialValue; }
}
class Program
{
  static void Main(string[] args)
  {
    Point point1 = new Point(5);
    Console.WriteLine("Before:" + point1.X);
    ChangePoint(point1);
    Console.WriteLine("After:" + point1.X);
    Console.ReadLine();
  }
  private static void ChangePoint(Point p)
  {
    p.X = 20;
  }
}

然后只需将单词"struct"更改为"class",就可以看到打印的内容。

您会得到不同的结果,因为结构是值类型,类是引用类型。

您的排序算法会修改两个列表中相同的按钮。如果你真的想这样做,你需要深入复制对象,即制作副本或每个按钮,而不仅仅是它们的引用。

但对列表进行排序的一个更好的解决方案是只对列表进行分类,即切换元素索引。(如button[i+1]=button[i]

您可以使用这里提到的方法

List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);
oldList.ForEach((item)=>
    {
        newList.Add(new YourType(item));
    });