2013-01-08 20 views
5

Questo progetto attuale è più una prova di concetto per un progetto più ampio. Ho due "tabelle" (rappresentate come liste di seguito), CatList e DogList, che hanno la stessa struttura di colonne. Desidero essere in grado di Concat o Union i due ed eseguire una query sul set risultante utilizzando LINQ. Mi è stato detto che implementando interfaces sarei stato in grado di raggiungere questi risultati.Tabelle concat/union in LINQ

Ecco quello che ho finora:

 static void Main(string[] args) 
    { 
     System.Console.Write("Hello World\n"); 
     Dog Dog1 = new Dog { name = "A", age = 1 }; 
     Dog Dog2 = new Dog { name = "B", age = 2 }; 
     Cat Cat1 = new Cat { name = "C", age = 3 }; 
     Cat Cat2 = new Cat { name = "D", age = 4 }; 

     List<Dog> DogList = new List<Dog>(); 
     List<Cat> CatList = new List<Cat>(); 
     DogList.Add(Dog1); 
     DogList.Add(Dog2); 
     CatList.Add(Cat1); 
     CatList.Add(Cat2); 

     var result = DogList 
       .Concat(CatList); 

    } 
} 

public interface iAnimal 
{ 
    string name { get; set; } 
    int age { get; set; } 
} 
public class Dog :iAnimal 
{ 
    public string name { get; set; } 
    public int age { get; set; } 
} 
public class Cat:iAnimal 
{ 
    public string name { get; set; } 
    public int age { get; set; } 
} 

posso accedere a qualsiasi dei membri di dati di qualsiasi dei miei oggetti creati utilizzando qualcosa di simile System.Console.Write(Dog1.name);, quindi penso che la mia implementazione di interfacce è corretta. Cosa deve essere cambiato nella mia dichiarazione LINQ per poter concat/unionare le mie liste in modo efficace.

Sono piuttosto nuovo a C# e programmazione orientata agli oggetti in generale, quindi si prega di soddisfare le vostre risposte per soddisfare il mio livello di conoscenza.

Grazie

EDIT mi scuso, come ho dimenticato di includere il messaggio di errore ottengo nel mio codice corrente.

Error 1 'System.Collections.Generic.List<InterfaceTest.Dog>' does not contain a definition for 'Concat' and the best extension method overload 'System.Linq.ParallelEnumerable.Concat<TSource>(System.Linq.ParallelQuery<TSource>, System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments 

Error 2 Instance argument: cannot convert from 'System.Collections.Generic.List<InterfaceTest.Dog>' to 'System.Linq.ParallelQuery<InterfaceTest.Cat>' 
+0

Spiacente, ho dimenticato di includere errori. La domanda è fissa. – Jeff

risposta

13

Il problema è che il compilatore non può capire che concatenando uno List<Dog> e uno List<Cat> si dovrebbe produrre una raccolta di iAnimal s. Per impostazione predefinita, vede un List<Dog> e si aspetta che la seguente collezione sia una raccolta di Dog.

Si può dire in modo esplicito per trattare tutto come un iAnimal questo fornendo il parametro generico per Concat, vale a dire

var result = DogList.Concat<iAnimal>(CatList); 

Si raggiunge quindi un result di tipo IEnumerable<iAnimal>.

Edit: Se sei bloccato in .NET 3.5, avrete bisogno di qualcosa di simile a

come 3.5 non può convertire automaticamente collection of something that inherits iAnimal-collection of iAnimal.

+3

Nota che questo richiede C# 4 per il supporto della covarianza. –

+1

Oh, davvero? Grazie Jon. (Sono apparentemente riuscito ad accettare la covarianza e non me ne accorgo quando lo sto usando.) – Rawling

+0

Questo ha risolto il mio problema (+1), ma interessante, i [documenti MSDN] (http://msdn.microsoft.com/en -us/library/bb397914.aspx) sembra suggerire di poter 'Concat' due oggetti senza questa tecnica e anche quando non condividono un'eredità comune –

3

Le liste generiche sono da diversi tipi (cani e gatti), è necessario "lanciare" li all'interfaccia di destinazione prima di concatenazione:

var list1 = DogList.Cast<IAnimal>(); 
var list2 = CatList.Cast<IAnimal>(); 

var bothLists = list1.Concat(list2); //optional .ToList() 
+0

Non l'ho provato, ma sembra che dovrebbe funzionare considerando che usa solo i metodi di estensione 'List'. Stavo cercando una soluzione 'LINQ' in quanto si tratta semplicemente di una prova del progetto concettuale per uno più grande. – Jeff

+1

@Jeff 'Cast' è un metodo LINQ, non un metodo' List'. – Servy

+0

Ah, interessante. Ignora il mio commento. – Jeff