Poongodi V Ответов: 3

Сравните два списка значений объектов в linq


У меня есть и класс сотрудника

public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Age { get; set; }
        public string Address { get; set; }
        public string ContactNo { get; set; }
    }


метод Fill
private static void FillEmployeeList(ref List<Employee> lt1, ref List<Employee> lt2)
        {
            lt1 = new List<Employee> {new Employee{ID=1,Name="Kavya",Age="24",Address="No.1,Nehru Street,Chennai",ContactNo="9874521456"},
            new Employee{ID=2,Name="Ravi",Age="24",Address="Flat No.25/A1,Gandhi Street,Chennai",ContactNo="9658745258"},
            new Employee{ID=3,Name="Lavnya",Age="30",Address="No.12,Shastri nagar,Chennai",ContactNo="5214587896"},
            new Employee{ID=4,Name="Rupa",Age="31",Address="No.23/5,Nehru Street,Chennai",ContactNo="9874521256"},
            new Employee{ID=5,Name="Divya",Age="32",Address="No.1/227,Nehru Street,Chennai",ContactNo="8541256387"},            
            };


    lt2 = new List<Employee> {new Employee{ID=1,Name="Kavya",Age="24",Address="No.1,Nehru Street,Chennai",ContactNo="9874521456"},
    new Employee{ID=2,Name="Ravindran",Age="30",Address="Flat No.25/A1,Gandhi Street,Chennai",ContactNo="9658745258"},
    new Employee{ID=3,Name="Chandru",Age="30",Address="No.12,Shastri nagar,Chennai",ContactNo="5214587896"},
    new Employee{ID=4,Name="Rakesh",Age="32",Address="No.23/5,Nehru Street,Chennai",ContactNo="9874021256"},
    new Employee{ID=5,Name="Suresh",Age="32",Address="No.1/227,Nehru Street,Chennai",ContactNo="8541056387"},
    new Employee{ID=11,Name="Suryakala",Age="28",Address="No.1,Pillayar koil Street,Chennai",ContactNo="9541204782"},
    new Employee{ID=12,Name="Thivya",Age="41",Address="No.42,Ellaiamman koil Street,Chennai",ContactNo="9632140874"},
    };
}


Сравнение двух списков,

protected List<Employee> ListCompare(List<Employee> lt1, List<Employee> lt2)
        {
            FillEmployeeList(ref lt1, ref lt2);
            List<Employee> lst = new List<Employee>();

            if (lt1.Count > 0 && lt2.Count > 0)
            {
                // Displaying Matching Records from List1 and List2 by ID

                var result = (from l1 in lt1
                              join l2 in lt2
                              on l1.ID equals l2.ID
                              orderby l1.ID
                              select new
                              {

                                  ID = l1.ID,
                                  Name = (l1.Name == l2.Name) ? "$" : (l2.Name + " (Modified)"),
                                  Age = (l1.Age == l2.Age) ? "$" : (l2.Age + " (Modified)"),
                                  Address = (l1.Address == l2.Address) ? "$" : (l2.Address + " (Modified)"),
                                  ContactNo = (l1.ContactNo == l2.ContactNo) ? "$" : (l2.ContactNo + " (Modified)")
                              }).ToList();

                // Displaying Records from List1 which is not in List2
                var result1 = from l1 in lt1
                              where !(from l2 in lt2
                                      select l2.ID).Contains(l1.ID)
                              orderby l1.ID
                              select new
                              {
                                  ID = l1.ID,
                                  Name = " Deleted",
                                  Age = " Deleted",
                                  Address = " Deleted",
                                  ContactNo = " Deleted"
                              };

                // Displaying Records from List1 which is not in List2
                var result2 = from l1 in lt2
                              where !(from l2 in lt1
                                      select l2.ID).Contains(l1.ID)
                              orderby l1.ID
                              select new
                              {
                                  ID = l1.ID,
                                  Name = l1.Name + " (Added)",
                                  Age = l1.Age + " (Added)",
                                  Address = l1.Address + " (Added)",
                                  ContactNo = l1.ContactNo + " (Added)"
                              };

                var res1 = result.Concat(result1).Concat(result2);

                foreach (var item in res1)
                {
                    Employee emp = new Employee();
                    //Response.Write(item + "<br/>");
                    emp.ID = item.ID;
                    emp.Name = item.Name;
                    emp.Age = item.Age;
                    emp.Address = item.Address;
                    emp.ContactNo = item.ContactNo;
                    lst.Add(emp);
                }
            }
            return lst;
        }


Я хочу, чтобы приведенный выше ListCompare в обобщении использовал любой король объектов не только для сотрудника, но и для другого класса (студент, человек и т. д.). Pls может ли кто-нибудь мне помочь?


отображаемые результаты,

<pre lang="c#">
List< employee> lt1 = новый список & lt;employee>();
List< employee> lt2 = новый список & lt;employee>();
List & lt;employee> resultset = новый список & lt;employee>();
// string value = " ID";
StringBuilder htmlTable = новый StringBuilder();
htmlTable.Добавлять("");
htmlTable.Добавлять("");
объект ResultSet = ListCompare(клеммами LT1, LT2, не);
по каждому элементу(ВАР элемента в результирующем наборе)
{
htmlTable.Добавлять("");
htmlTable.Добавлять("");
htmlTable.Добавлять("");
htmlTable.Добавлять("");
htmlTable.Добавлять("");
htmlTable.Добавлять("");
htmlTable.Добавлять("");
}
htmlTable.Добавлять("
ИДЕНТИФИКАТОР Имя Возраст Адрес ContactNo
" + пункт.ИДЕНТИФИКАТОР + " " + пункт.Имя + " " + пункт.Возраст + " " + пункт.Адрес + " " + пункт.ContactNo + "
");
PlaceHolder1.Контроля.Добавить (новый литерал { Text = htmlTable.Метод toString() });


Выход:
ID имя возраст адрес ContactNo
---------------------------------------------------------------------------------
1 $ $ $ $
2 Равиндран (Модифицированный) 30 (Модифицированный) $ $
3 Chandru (Измененные) 30 (Изменено) $ $
4 Ракеш (Модификации) 32 (С Изменениями) 9874021256 $ (Измененная)
5 Суреш (Изменен) $ 8541056387 $ (Измененная)
11 Suryakala (Добавлен 28) (Добавлено) № 1, Пиллаяр
улица Койл,
Ченнаи (Добавлено) 9541204782 (Добавлено)
12 Тивья (добавлено) 41 (добавлено) № 42, Эллайамман Койл
Улица, Ченнаи(Добавлено) 9632140874 (добавлено)

Что я уже пробовал:

Получение правильного вывода, но я хочу обобщенно использовать его для любого класса объектов, таких как студент, человек и т. д.

3 Ответов

Рейтинг:
2

BillWoodruff

Цитата:
"Я хочу, чтобы вышеприведенный ListCompare в обобщении использовал любой король объектов"
Это, как советует вам здесь OriginalGriff, трудно; для этого потребуется сложное использование отражения, и я думаю, что вам придется каким-то образом (пользовательские атрибуты ?) добавлять метаданные к экземплярам класса, которые вы сравниваете, чтобы сделать списки полей, свойств и т. д."

... редактировать ...

Здесь на CodeProject есть серия из четырех частей Эхсана Саджада о равенстве в .NET: [^].

... конец редактирования ..

На GitHub есть проект с открытым исходным кодом [^], "Сравнить-продажи-объекты," очень активно разрабатывается Грег Finzer и другим, что берет на себя эту трудную задачу, и которые, по моему опыту, вполне здравая. Вы можете установить этот проект с помощью NuGet: [^].

Текущий набор функций Compare-Net-Objects:

* Сравнение детей (включено по умолчанию)
* Обработка деревьев с детьми, указывающими на родителей (круговые ссылки)
* Сравнение Примитивных Типов
* Сравнение Структур
* Сравнение Объектов IList
* Сравнение одномерных и многомерных массивов
* Сравнение Объектов IDictionary
* Сравнение общедоступных полей и свойств класса
* Сравнение частных полей и свойств (по умолчанию выключено)
* Сравнение Перечислений
* Сравнение Временных Интервалов
* Сравнение GUID
* Сравнение классов, реализующих IList, с Индексаторами
* Сравнение Данных Набора Данных
* Сравнение Доступных Данных
* Сравнение Данных DataRow
* Сравните LinearGradient
* Сравните Хэш-Набор
* Сравнение URI
* Сравните IPEndPoint
* Сравнение типов типов (RuntimeType)
* Исходный код на языке Си#
* Тестовый Проект NUnit Включен
* Возможность загрузки параметров из конфигурационного файла для использования с powershell
* Несколько вариантов конфигурации для сравнения частных элементов, игнорируя конкретные элементы, включая конкретные элементы.
* Кэширование отражения информации о свойствах и полях для повышения производительности
* Богатый список различий или простая строка различий
* Поддержка пользовательских функций сравнения
* ElapsedMilliseconds указывает, сколько времени заняло сравнение.
* Возможность IgnoreCollectionOrder
* поточно-ориентированный
* Возможность перехода в конфигурацию
* Возможность игнорировать сравнение индексаторов
* Возможность игнорировать типы
* Фильтрация элементов интерфейса
* Возможность рассматривать string. empty и null как равные
* Вне Всякого Сравнения Отчетов
* Отчет WinMerge
* Отчет CSV
* Удобное Для Пользователя РЕПО


Poongodi V

спасибо. Любой пример кодирования доступен для сравнения двух списков с помощью Compare .Чистые объекты. Если это так, пожалуйста, поделитесь.

Рейтинг:
1

Poongodi V

Пожалуйста, обратитесь к приведенной ниже ссылке для получения решения
c# - сравнение двух списков объектов с помощью LINQ динамически-переполнение стека[^]


BillWoodruff

Приведенная выше ссылка приводит к решению, которое сравнивает два списка объектов с одинаковыми структурами (т. е. объекты являются экземплярами одного класса, структуры, типа) с помощью Linq. Это легко, но вы спросили о возможном сравнении списков объектов, которые могут иметь разные внутренние структуры: это сложно !

Poongodi V

да. Я хочу, чтобы все было так, как вы сказали, но все равно ищу решение. Пожалуйста, поделитесь, если у вас есть какие-либо идеи.

Рейтинг:
0

OriginalGriff

В значительной степени вы не можете обобщить его так, как хотите - если хотите сравнить по полям, специфичным для класса Student или Person.
Вы можете сделать это, если создадите базовый класс и выведете из него все остальные классы:

public class Employee
    {
    public int ID { get; set; }
    public string Name { get; set; }
    public string Age { get; set; }
    public string Address { get; set; }
    public string ContactNo { get; set; }
    public List<T> ListCompare<T>(List<T> lt1, List<T> lt2) where T:Employee
        {
        List<T> lst = new List<T>();
        ...
        return lst;
        }
    }

Вы даже можете сделать сотрудника abstract поэтому вы не можете случайно создать его экземпляр.


Poongodi V

Спасибо.

OriginalGriff

Пожалуйста!