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のアイテムと一致します...objectBforeachアイテムを設定したい...

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

この場合、リストを変更しているので、実際にはaforeachが適切なアプローチだと思います。ただし、コードを少し単純化できる可能性があります。

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

リードの答えを拡張します。リストには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();

Update2

私は別のアプローチを考えました-あなたのシナリオに応じて、怠惰なメカニズムがあなたのために働くかもしれませんか?

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;
   }
}

JoinLINQメソッドを使用すると、次のことができます。

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 に答える