2011-12-08 2 views
1

J'ai deux listes. Les types des deux listes héritent du même type de base. Je veux les parcourir et faire des opérations qui n'utilisent que la fonctionnalité de la classe de base sans avoir deux boucles foreach fondamentalement identiques l'une après l'autre.Itération à travers deux listes de deux classes héritées (de la même classe de base)

Je ne peux pas copier les listes vers une autre liste ou quelque chose du genre, car j'ai besoin d'utiliser les listes dans leur forme originale séparément après que l'opération soit terminée.

Existe-t-il un moyen de le faire sans écrire de fonction?

class Program 
{ 
    static void Main(string[] args) 
    { 
     // I have two lists of inherited classes 
     List<Babby1> list1 = returnBabby1(); 
     List<Babby2> list2 = returnBabby2(); 

     // I want to iterate through both, and do the same thing, which is a part 
     // of the base class functionality. 
     // Basically I want this to be a single foreach loop. 
     foreach (Babby1 item in list1) 
      item.var = 50; 

     foreach (Babby2 item in list2) 
      item.var = 50; 

     // I have to send them as separate lists, the type being the original (inherited) class 
     sendBabby1(list1); 
     sendBabby2(list2); 
    } 

    static void sendBabby1(List<Babby1> list) 
    { 
    } 

    static void sendBabby2(List<Babby2> list) 
    { 
    } 

    static List<Babby1> returnBabby1() 
    { 
     return new List<Babby1>(); 
    } 

    static List<Babby2> returnBabby2() 
    { 
     return new List<Babby2>(); 
    } 
} 

class Base 
{ 
    public int var; 
} 

class Babby1 : Base 
{ 
    public int var1; 
} 

class Babby2 : Base 
{ 
    public int var2; 
} 
+1

Vous avez deux listes distinctes, de sorte que vous ne pouvez pas les énumérer comme l'un sans créer une nouvelle liste. – slugster

Répondre

6

Cela devrait faire l'affaire. ..

foreach (var item in list1.Concat<Base>(list2)) 
{ 
    // Do your thing 
} 

EDIT: J'ai changé Union-Concat que je pense que ce s probablement plus approprié.

+0

Cela fonctionne parfaitement, merci! Avec Union, cela prend beaucoup plus de temps (les listes sont très volumineuses), puis une exception OutOfMemory est générée, mais Concat fait le travail. – svinja

+0

'Union' va comparer l'égalité entre chacun des éléments dans les listes, alors que' Concat' est juste ... bien ... concaténant eux! –

+0

svinja, si cela a résolu votre problème s'il vous plaît envisager de l'accepter comme la réponse ... cela permettra aux autres de savoir que votre problème est résolu, et aider les autres à trouver une solution s'ils rencontrent des problèmes similaires. (c'est la grosse coche à côté de cette réponse!) –

0

Il suffit d'utiliser la classe de base, comme ceci:

List<Babby> list = new List<Base>(); 
list.AddRange(returnBabby1()); 
list.AddRange(returnBabby2()); 

foreach (Base item in list) 
    item.var = 50; 

sendBabby1(list.OfType<Babby1>().ToList()); 
sendBabby2(list.OfType<Babby2>().ToList()); 

(Bien sûr, cela suppose que vous avez la variable que vous définissez déclaré dans la classe de base)

0

Vous pouvez utiliser le covariance de IEnumerable<T> afin d'y parvenir, si vous prévoyez de simplement itérer les listes et non ajouter des éléments ou effectuer d'autres opérations sur la liste:

static SendBaby(IEnumerable<Base> list) 
{ 
    ... 
} 
... 
SendBaby(list1) 
SendBaby(list2) 
0

Vous pouvez utiliser une boucle , en utilisant Count à la place. (Si la comparaison ne consomment cycles CPU supplémentaires.)

for(int i=0;i<baby1.Count||i<baby2.Count;i++) 
{ 
    if(baby1.Count<i) 
     baby1[i].field = 50; 
    if(baby2.Count<i) 
     baby2[i].field = 50; 
} 
0

Cela fait assez bien:

 var babies1 = new List<Baby1>(5); 
     for (int i = 0; i < 5; i++) 
     { 
      babies1.Add(new Baby1 { Name = "Babies1 " + i, Var1 = 1}); 
     } 

     var babies2 = new List<Baby2>(5); 
     for (int i = 0; i < 5; i++) 
     { 
      babies2.Add(new Baby2 { Name = "Babies2 " + i }); 
     } 

     foreach (Baby b in babies1.Union<Baby>(babies2)) 
     { 
      b.Var1 = 50; 
     } 

     foreach (var baby2 in babies2) 
     { 
      Console.WriteLine(baby2.Var1); 
     } 

     foreach (var baby1 in babies1) 
     { 
      Console.WriteLine(baby1.Var1); 
     } 
Questions connexes