2013-08-19 9 views
5

ho bisogno di fare qualcosa di simile:Passando oggetto di tipo anonimo come parametro di un metodo

public class carros 
{ 
    public int id { get; set; } 
    public string nome { get; set; } 
} 

public void listar_carros() 
{ 
    List<carros> cars = new List<carros>(); 
    cars.Add(new carros{ id= 1, nome = "Fusca" }); 
    cars.Add(new carros{ id= 2, nome = "Gol" }); 
    cars.Add(new carros{ id= 3, nome = "Fiesta" }); 

    var queryResult = from q in cars 
         where q.nome.ToLower().Contains("eco") 
         orderby q.nome 
         select new { q.nome, q.id }; 

    doSomething(queryResult) 
} 

ho bisogno di passare la variabile queryResult di funzionare doSomething(). Ho cercato di utilizzare un tipo dinamico, List<T> oggetto, ma niente funziona

public void doSomething(???? queryResult) 
{ 
    foreach (carros ca in queryResult) 
    { 
     Response.Write(ca.nome); 
     Response.Write(" - "); 
     Response.Write(ca.id); 
    } 
} 
+1

In Visual Studio, è possibile passare con il mouse sulla parola chiave 'var' per visualizzare il tipo di risultato generato. – lukegravitt

risposta

10

In generale, è quasi sempre una cattiva idea di passare tipi anonimi tra i metodi.

È necessario creare un tipo personalizzato per contenere i valori nome e id, quindi costruirlo anziché un tipo anonimo.


Nel tuo caso, hai già una classe che avrebbe funzionato: carros. Si può solo implementare la query per creare invece:

var queryResult = from q in cars 
    where q.nome.ToLower().Contains("eco") 
    orderby q.nome 
    select new carros {q.nome, q.id}; 

tuo metodo sarebbe allora:

public void doSomething(IEnumerable<carros> queryResults) 
+0

Puoi spiegare perché questa è una cattiva idea? Ha un oggetto già chiamato 'Carros' che ha' nome' e 'id' – itanex

+0

puoi spiegare? –

+3

@FelipeMaricatoMoura: il motivo per cui è una cattiva idea è perché il tipo anonimo che hai creato è * anonimo *. Cioè: non c'è modo di costruirlo al di fuori della query LINQ in cui è stato utilizzato (al di fuori della riflessione hackeraggio). Per quanto utili come i tipi anonimi, sono giustamente limitati nella portata del loro metodo iniziale. Se vuoi passarli, hanno chiaramente una rilevanza oltre quella portata iniziale e quindi meritano un nome e una dichiarazione. –

2

Non è possibile passare i tipi anonimi * al di fuori del campo di applicazione del metodo corrente. Usa il tuo tipo carros:

public void listar_carros() 
{ 
    List<carros> Lcars = new List<carros>(); 
    Lcars.Add(new carros(1, "Fusca")); 
    Lcars.Add(new carros(2, "Gol")); 
    Lcars.Add(new carros(3, "Fiesta")); 

    var qry = from q in Lcars 
       where q.nome.ToLower().Contains("eco") 
       orderby q.nome 
       select q; 

    doSomething(qry); 

} 

public void doSomething(IEnumerable<carros> qry) 
{ 

    foreach (carros ca in qry) 
    { 
     Response.Write(ca.nome); 
     Response.Write(" - "); 
     Response.Write(ca.id); 
     //Response.Write(ca); 
     Response.Write("<br />"); 
    } 
} 

* È possibile passarli solo come object, che è in gran parte inutile dal momento che si vorrebbe usarli in maniera forte tipizzato.

+0

non funziona doSomething (qry) la linea mostra l'errore –

+0

Puoi condividere l'errore di compilazione? –

+0

mi dispiace funziona bene usando un selec q; ma non funziona per selezionare nuovi carros {q.nome, q.id}; oppure selezionare new {q.nome, q.id}; sai cosa? –

2

Perché non dichiarare il nuovo oggetto come tipo carros?

var qry = from q in Lcars 
      where q.nome.ToLower().Contains("eco") 
      orderby q.nome 
      select new carros {q.nome, q.id}; 

tuo parametro sarebbe quindi:

IEnumerable{carros} 
+0

O solo 'selezionare q' – Magnus

+0

non funzionano nuovi carros {} mostrare un erros in nuova parola –

+0

erro: Errore 'testiLINQ.carros' non contiene un costruttore che accetta 0 argomenti –

3

Volevo solo carillon in materia di passaggio tipi anonimi, mentre è stato detto che il suo cattivo juju passare anonmyous tipi, è possibile ... se davvero voleva (sfruttando dinamica)

public void Anon() 
{ 
    var x = new {foo = "bar"}; 

    AnonReciever(x); 
} 

public static void AnonReciever(dynamic o) 
{ 
    Console.WriteLine(o.foo); 
} 

E questa stampa bar nessun problema.

Non lo consiglio però. Meglio usare un oggetto personalizzato, che hai già.

+0

non funziona dinamico mostra errore "spazio dei nomi dinamico non può essere trovato" –

+0

http://stackoverflow.com/a/14760410/310196 – devshorts