otrzymuje następujące interfejsu i dwie klasy:Uproszczenie pętli foreach z LINQ (wybierając dwa obiekty w każdej iteracji)
public interface IMyObj
{
int Id { get; set; }
}
public class MyObj1 : IMyObj
{
public MyObj1(int id) { Id = id; }
public int Id { get; set; }
public override string ToString() => $"{GetType().Name} : {Id}";
}
public class MyObj2 : IMyObj
{
public MyObj2(int id) { Id = id; }
public int Id { get; set; }
public override string ToString() => $"{GetType().Name} : {Id}";
}
A biorąc pod uwagę następujące logiki, że ich zastosowań:
var numbers = new[] { 1, 5, 11, 17 };
var list = new List<IMyObj>();
foreach (var n in numbers)
{
// I'd like to simplify this part with LINQ...
list.Add(new MyObj1(n));
list.Add(new MyObj2(n));
}
Assert.AreEqual(8, list.Count);
Test przechodzący i widzę dokładnie to, czego chcę - dwie instancje obiektu na numer:
Count = 8
[0]: {MyObj1 : 1}
[1]: {MyObj2 : 1}
[2]: {MyObj1 : 5}
[3]: {MyObj2 : 5}
[4]: {MyObj1 : 11}
[5]: {MyObj2 : 11}
[6]: {MyObj1 : 17}
[7]: {MyObj2 : 17}
Moje pytanie brzmi: jak uprościć logikę pętli z LINQ? Myślę, że może być elegancki sposób na to samo z operatorem SelectMany
, ale nie byłem w stanie wyprodukować tego samego wyjścia.
Należy zauważyć, że to nie daje tej samej kolejności, co oryginalny kod OP, w przeciwieństwie do 'SelectMany'. Sugerowałbym również użycie 'Concat' zamiast' Union', ponieważ zachowanie ustalone nie zostało określone ... i wreszcie, musisz określić argumenty typu używając interfejsu, ponieważ inaczej nie skompiluje się. –