2009-08-25 7 views
43

So che non posso scrivere un metodo come:C'è un modo per restituire il tipo Anonymous dal metodo?

public var MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"}; 
} 

posso fare altrimenti:

public object MyMethod() 
{ 
    return new{ Property1 = "test", Property2="test"} 
} 

ma io non voglio fare la seconda opzione, perché, se lo faccio , Dovrò usare la riflessione.


Perché io voglio farlo:

oggi ho un metodo all'interno della mia pagina aspx che restituisce un DataTable, come risultato e io non posso cambiarlo, stavo cercando di convertire questo DataTable a un Metodo anonimo con le proprietà con cui voglio lavorare. Non volevo creare una classe solo per farlo e dato che avrò bisogno di eseguire la stessa query più di una volta, ho pensato di creare un metodo che restituisca un tipo anonimo sarebbe una buona idea.

+0

Cosa vorresti usare? Come sei giunto alla conclusione che vorresti fare qualcosa del genere? – Guffa

+0

@Guffa, ho un metodo nella mia pagina aspx che restituisce un datatable come risultato, stavo cercando di convertire questo datatable in un metodo anonimo con le proprietà con cui voglio lavorare. Non volevo creare una classe solo per farlo e poiché avrò bisogno di eseguire la stessa query più volte, per creare un metodo che restituisce un metodo anonimo, sarebbe una buona idea. – Cleiton

+1

@Cleiton: sarà necessario molto meno sforzo per creare una classe per contenere i dati. Mi sono reso conto che solo perché posso usare i tipi anonimi per manipolare facilmente i dati, non significa che dovrei smettere di creare classi per definire quei tipi quando ho bisogno di passarli da un livello all'altro. – Jagd

risposta

57

Restituirlo come System.Object è il solo modo per restituire un tipo anonimo da un metodo. Sfortunatamente non esiste un altro modo per farlo poiché i tipi anonimi sono stati progettati specificamente per impedirne l'uso in questo modo.

Ci sono alcuni trucchi che è possibile fare in concomitanza con la restituzione di uno Object che consente di avvicinarsi. Se sei interessato a questa soluzione alternativa, leggi Can't return anonymous type from method? Really?.

Disclaimer: Anche se l'articolo che ho collegato mostra una soluzione che non significa che sia una buona idea farlo. Vorrei fortemente scoraggiare l'utilizzo di questo approccio quando la creazione di un tipo normale sarebbe più sicura e più facile da capire.

+10

Va notato che questa non è un'idea consigliata . Intellisense non riconoscerà più le proprietà fortemente tipizzate del tipo anonimo (Property1 e Property2 del tuo esempio). In realtà, puoi usare la riflessione per ottenere le proprietà, ma puoi anche colpire il pollice con il martello per tutto il lavoro che stai facendo, e per non parlare di aver appena preso qualcosa che avrebbe dovuto semplificarti la vita , ma in effetti ha reso più difficile. – Jagd

+0

+1 non avrei potuto dirlo meglio di me stesso. Sì, può essere fatto, ma ciò non significa che sia una buona idea. –

+0

Si può fare! _È solo un p.i.t.a._ –

1

No, i tipi anonimi non possono esistere al di fuori del contesto in cui sono stati creati e, di conseguenza, non possono essere utilizzati come metodo restituito. È possibile restituire l'istanza come object, ma è molto più utile creare in modo esplicito il proprio tipo di contenitore per questo scopo.

0

Scusa, davvero non dovresti farlo. Puoi aggirarlo con il riflesso o creando un metodo di supporto generico per restituire il tipo per te, ma farlo sta davvero andando contro la lingua. Basta dichiarare il tipo in modo che sia chiaro cosa sta succedendo.

2

Penso che Andrew Hare abbia ragione, devi solo restituire "oggetto". Per un commento editoriale, mi sento di trattare con oggetti grezzi nel codice OO può essere un "odore di codice". Ci sono casi in cui è la cosa giusta da fare, ma la maggior parte delle volte, sarebbe meglio definire un'interfaccia da restituire, o usare una sorta di tipo di classe base, se hai intenzione di restituire i tipi correlati.

1

No, non è disponibile alcun supporto per espandere l'ambito della classe anonima all'esterno del metodo. Al di fuori del metodo, la classe è veramente anonima e la riflessione è l'unico modo per accedere ai suoi membri.

13

La soluzione più semplice è creare una classe, inserire i valori nella proprietà e quindi restituirla. Se i tipi anonimi ti stanno rendendo più difficile la vita, non li stai utilizzando correttamente.

13
public object MyMethod() 
{ 
    return new 
    { 
     Property1 = "test", 
     Property2 = "test" 
    }; 
} 

static void Main(..) 
{ 
    dynamic o = MyMethod(); 
    var p1 = o.Property1; 
    var p2 = o.Property2; 
} 
21

In alternativa, è possibile utilizzare la classe Tuple in .NET 4.0 e superiori:

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Tuple<string, string> Create() 
{ 
return Tuple.Create("test1", "test2"); 
} 

allora è possibile accedere alle immobili come questo:

var result = Create(); 
result.Item1; 
result.Item2; 
+8

Divertente. Sono venuto qui cercando un'alternativa all'utilizzo di tuple come tipi di ritorno. – SixOThree

6

Nonostante gli avvertimenti sul fatto che questa è una buona idea o no ... A dynamic sembra lavorare bene per un metodo privato.

private dynamic MyMethod() 
{ 
    return new { Property1 = "test", Property2 = "test" } 
} 
+0

Penso che non sia il massimo, dal momento che la dinamica si baserà su tutti i tipi di dati, incluso l'oggetto, in modo tale che tu possa essere migliore con l'oggetto, con un sovraccarico minore. – MrKekson

Problemi correlati