У меня есть два списка: оригинал, другой - копия оригинала
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);
}
в вышеупомянутых трех ситуациях оба списка сортируются :( Я хочу просто отсортировать только экземплярButtonList, может ли кто-нибудь указать мои ошибки, которые я здесь сделал?
Обновлено: мой алгоритм сортировки вставки ниже
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;
}
Собственно говорящий вопрос не тупой. Поскольку вы не меняете Button, нет необходимости в глубоком клонировании. Ваша проблема, вероятно, где-то в другом месте. Вот пример
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();
}
Это печатает
аа
куб.см
бб
а потом
аа
бб
куб.см
Обновить
Ваш ARE меняет кнопку, поэтому вам нужна глубокая копия. Используйте это, чтобы создать новый список.
using System.Linq;
copyButtonList = buttonList.Select(ee => new Button() { Text= ee.Text}).ToList();
Под "Изменение кнопки" я имею в виду строки, подобные этому
button.ElementAt(i + 1).Text = key;
У вас может быть 2 списка, но они оба "указывают"/имеют одни и те же объекты. Когда вы меняете текст кнопки в списке 1, это означает, что объект также изменяется и в списке 2.
Вам нужно понять, что такое тип значения, а также тип ссылки и их различия. Вот некоторые ссылки, которые помогут вам
http://www.albahari.com/valuevsreftypes.aspx
В чем разница между ссылочным типом и типом значения в С#?
Также запустите на своем компьютере следующее консольное приложение и посмотрите, что напечатано
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));
});
ForEach
и лямбда вместо foreach
, вероятно, является плохой идеей.