2

我有 2 个对象:

public class ClassA
{
   public int Id
   public string name;

   public ClassB myObjectB;

}
public class ClassB
{
   public int Id
   public string name
}

<ClassA> <ClassB> 有 2 个列表 List1 中的某些项目按 Id 与 List2 上的项目匹配...我想为每个项目设置 objectB ...

foreach(ClassA item in List1)
{
   ClassB obj = (from b in List2 where b.Id == item.Id select b).SingleOrDefault()
   if(obj != null)
   {
       item.myObjectB = obj; 
       ////////break;    <- ignore this
   }
}

这个解决方案对我有用,但我只是想知道是否有更好的方法来做到这一点,而不是 Foreach

谢谢大家的帮助!!!

4

4 回答 4

8

我认为 a foreach,在这种情况下,实际上是合适的方法,因为你正在改变你的列表。但是,您可能会稍微简化代码:

foreach(ClassA item in List1)
{
    item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id);
}

这将每次设置该项目,但null如果没有匹配项,它将被设置为。如果您已经有项目myObjectB并且将它们设置为 null 是不合适的,您可以使用:

foreach(ClassA item in List1)
{
    item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id) ?? item.myObjectB;
}
于 2012-12-07T00:14:31.210 回答
1

扩展 Reed 的答案..您实际上可以在单行中执行此操作,因为列表具有 ForEach 方法。

List1.ForEach(item => item.myObjectB = List2.FirstOrDefault(b => b.Id == item.Id) ?? item.myObjectB);
于 2012-12-07T00:19:24.087 回答
0
List<ClassA> list1 = new List<ClassA>();
List<ClassB> list2 = new List<ClassB>();

list1.Add(new ClassA { Id = 2, name = "a2" });
list1.Add(new ClassA { Id = 3, name = "a3" });
list1.Add(new ClassA { Id = 4, name = "a4" });
list1.Add(new ClassA { Id = 5, name = "a5" });

list2.Add(new ClassB { Id = 1, name = "b1" });
list2.Add(new ClassB { Id = 2, name = "b2" });
list2.Add(new ClassB { Id = 4, name = "b4" });
list2.Add(new ClassB { Id = 5, name = "b5" });

// Goal is to set ClassA::myObjectB from List1 to 
// matching instance (if any) of ClassB from List2
var query = 
    from a in list1
    from b in list2
    where a.Id == b.Id
    select Tuple.Create(a, b);  
foreach (var element in query)
    element.Item1.myObjectB = element.Item2;

更新

或者,如果您真的不想要一个 for 循环,我刚刚意识到您可以使用赋值返回一个值的事实,同时在混淆代码竞赛中输入:)

(from a in list1
 from b in list2
 where a.Id == b.Id
 select a.myObjectB = b).ToList();

更新2

我只是想到了另一种方法-根据您的情况,惰性机制可能对您有用吗?

public class ClassA
{
   public int Id
   public string name;

   private ClassB myObjectB;
   public ClassB MyObjectB { 
      get { return myObjectB ?? (myObjectB = list2.FirstOrDefault(x => this.Id == x.Id)); } 
   }
}
于 2012-12-07T00:22:37.300 回答
0

类定义如下:

class ClassA {
   public int Id { get; private set; }
   public string name { get; private set; }

   public ClassB myObjectB { get; set; }

   public ClassA(int pId, string pName) {
      Id = pId;
      name = pName;
   }
}

class ClassB {
   public int Id { get; private set; }
   public string name { get; private set; }

   public ClassB(int pId, string pName) {
      Id = pId;
      name = pName;
   }
}

您可以使用 LINQJoin方法执行以下操作:

var listA = new List<ClassA> {
   new ClassA(1, "OneA"),
   new ClassA(2, "TwoA"),
   new ClassA(3, "ThreeA")
};

var listB = new List<ClassB> {
   new ClassB(1, "OneB"),
   new ClassB(2, "TwoB"),
   new ClassB(4, "FourB")
};

listA
.Join(
   listB,
   itemA => itemA.Id,
   itemB => itemB.Id,
   (itemA, itemB) => new { ItemA = itemA, ItemB = itemB }
).ForEach(pair => pair.ItemA.myObjectB = pair.ItemB);

listA.ForEach(itemA => Console.WriteLine(
   "{0} maps to {1}",
   itemA == null
      ? "null"
      : itemA.name,
   (itemA == null || itemA.myObjectB == null)
      ? "null"
      : itemA.myObjectB.name
));

输出是:

OneA maps to OneB
TwoA maps to TwoB
ThreeA maps to null
于 2013-09-07T00:06:00.597 回答