Linq 合并2个不同类型的列表(备选方案)
在C V4中,我有两个通用列表列表列表L1和列表L2 我的问题是:type1有一个名为key1的属性,type2有一个名为key2的属性,我想在key1=key2上将L1和L2合并到一个唯一的列表中Linq 合并2个不同类型的列表(备选方案),linq,list,join,merge,Linq,List,Join,Merge,在C V4中,我有两个通用列表列表列表L1和列表L2 我的问题是:type1有一个名为key1的属性,type2有一个名为key2的属性,我想在key1=key2上将L1和L2合并到一个唯一的列表中 我需要以动态方式合并这些属性,因为我不知道这两个类的属性,我只知道每个类型的第一个属性是主键。通过说“属性”,我假设您引用的是属性或字段。 var foo = (from type1 in list1 join type2 in list2 on type1.Id equals
我需要以动态方式合并这些属性,因为我不知道这两个类的属性,我只知道每个类型的第一个属性是主键。通过说“属性”,我假设您引用的是属性或字段。
var foo = (from type1 in list1
join type2 in list2 on type1.Id equals type2.Id
select new {type1, type2}).ToList();
请不要使用“属性”,因为这很容易混淆,并且意味着完全不同的事情:
[Attribute]
class type1
{
public int Field;
public int Property { get; set; }
}
所以,您有type1和type2,并且希望基于类中的第一个字段或属性将它们合并到一个列表中。若您知道属性的名称,最简单的实现就是使用dynamics,假设Prop1和Prop2属性名称:
var foo =
(from type1 in list1
join type2 in list2 on ((dynamic)type1).Prop1 equals ((dynamic)type2).Prop2
select new {type1, type2}).ToList();
由于情况并非如此,并且我们希望在类中选择“first”字段或属性,所以我们唯一的方法就是使用反射。如果知道类中只有属性或字段,则可以使用简单实现:
var t1 = typeof(type1);
var t2 = typeof(type2);
//replace with .GetFields() if neccessary
var p1 = t1.GetProperties()[0]; // find first declared property of type1
var p2 = t2.GetProperties()[0]; // find first declared property of type2
var foo = (from obj1 in list1
join obj2 in list2 on p1.GetValue(obj1,null) equals p2.GetValue(obj2,null)
select new {obj1, obj2}).ToList();
如果类中的字段和属性混合在一起,则可以使用FindMembersMemberTypes.Field | MemberTypes.Property…列出所有成员,但这种方法有一个问题-字段总是重新定位到类的开头,尽管字段顺序似乎保持不变,在以下情况下,F1将始终作为类的第一个成员返回,GetFields将返回F1、F2和GetProperties-P1,此[]:
class A
{
public int P1 { get;set;}
public int F1;
public int this[int x] { get{return x;} set {} }
public int F2;
}
此外,这种方法还存在其他问题:
如果您的第一个属性是索引器呢?在上面的示例中,int this[…]
如果您的第一个字段/属性返回的对象没有为Equals实现重载,该怎么办?
如果您的第一个属性没有实现getterravel,但可能实现呢?等
通常,当您不知道字段/属性名称,并且依赖它们在类中的相对位置时,这种设计被认为是不好的。引用:
…GetMembers方法不按特定顺序返回成员,如字母顺序或声明顺序。您的代码不能依赖于成员返回的顺序,因为顺序不同。您所说的“第一个属性”是什么意思?我有两个列表:list1 list2每个类都有许多属性,因此第一个属性是List中每个对象的主键感谢您的回答,如果我不知道每个类的第一个属性的名称呢?