我有两种类型:
class Person
{
public string Name {get;set;}
public string Car {get;set;}
}
和第二种类型:
class Employee
{
public string Name {get;set;}
public string Salary {get;set;}
}
其中属性 名称相同(两种类型)。
我也得到了列表:
List<Person> _ListPerson = new List<Person>
List<Employee> _ListEmployee = new List<Employee>();
我添加了一些项目:
_ListPerson.Add( new Person { Name = "Jora" , Car = "BMW" };
_ListPerson.Add( new Person { Name = "Andrew" , Car = "Audi" };
_ListPerson.Add( new Person { Name = "Vasya" , Car = "Jiguli" };
_ListPerson.Add( new Person { Name = "Vasya" , Car = "Mercedes" };
_ListPerson.Add( new Person { Name = "Andy" , Car = "Renault" };
_ListEmployee.Add(new Employee { Name = "Vasya", Salary = "1000$"};
_ListEmployee.Add(new Employee { Name = "Andy", Salary = "200$"};
_ListEmployee.Add(new Employee { Name = "Andrew", Salary = "5000$"};
_ListEmployee.Add(new Employee { Name = "Jora", Salary = "100$"};
出于某种原因,我需要联合这些类型:
List<Object> People = New List<Object>();
People.AddRange(_ListPerson);
People.AddRange(_ListEmployee);
那么我如何通过lambda表达式排序这些家伙呢? 目前,我正在做这样的事情:
var _TEMP = _List.OfType<Person>().GroupBy(x => x.Name);.... //etc ,how i can use order by for these two types? Because oftype works only for one type.
答案 0 :(得分:4)
最简单的方法是Person
和Employee
共享一些公共基类或实现公共接口。例如:
public interface IName
{
string Name { get; }
}
class Person : IName
{
public string Name { get; set; }
public string Car { get; set; }
}
class Employee : IName
{
public string Name { get; set;}
public string Salary { get; set;}
}
然后,您可以使用以下常见类型创建列表,而不是创建List<object>
并使用OfType
:
var people = new List<IName>();
people.AddRange(_ListPerson);
people.AddRange(_ListEmployee);
和小组:
var grouped = people.GroupBy(x => x.Name);
虽然您提到要排序,但实际上可以使用OrderBy
或OrderByDescending
进行排序:
var sorted = people.OrderBy(x => x.Name);
答案 1 :(得分:1)
正确这样做的方法是要么有一个共同的界面(根据查尔斯的答案)或一个共同的基类(正如彼得在查尔斯回答的评论中所建议的那样)。
由于员工很可能是 Person
,因此我认为让Employee
派生自Person
更有意义。所以:
public class Person
{
public string Name { get; set; }
public string Car { get; set; }
}
public class Employee : Person
{
public string Salary { get; set;}
}
IName
界面看起来有点不自然。当然,这不是模拟它的唯一方法。您还可以说Person
有一个作业:
public class Person
{
public string Name { get; set; }
public string Car { get; set; }
public Job Job { get; set; }
}
public class Job
{
public string Salary { get; set;}
public Person Employee { get; set; }
}
但是,如果您完全陷入困境且无法更改Person
和Employee
类(可能来自某些第三方来源),那么可以执行像这样的东西:
var temp = People.Cast<dynamic>().OrderBy(a => a.Name);
将您的列表强制转换为dynamic
,以便检查Name
属性只会在运行时而不是编译时进行。但是,请注意,如果您在People
列表中添加了一些没有Name
属性的内容,那么您将收到运行时错误。
另一种选择是做这样的事情:
var tenp = People.OrderBy(a => {
string t = null;
if (a is Person) {
t = ((Person)a).Name;
}
else if (a is Employee) {
t = ((Employee)a).Name;
}
return t;
});
哪个更详细,但不需要dynamic
。但是,在这种情况下,由于我没有添加else
子句,因此任何非Person
或Employee
的内容都将在null
上排序,而 var abc;
(function ($, W, D) {
abc = {};
可能不会是理想的行为。
希望这些解决方法的缺点将使大多数人相信,正确设计类层次结构以避免此问题会更好。即使你坚持使用你所给的类,根据具体用法,它可能值得将它们转换为更合理的层次结构,然后再使用它。