Qual è il tipo di ritorno di una class anonima

Ho una class che aveva un tipo di restituzione di stringa. Ora trovo che devo restituire più di una stringa. Stavo pensando di restituire qualcosa come di seguito:

public string Test() { return ( new { ID = 5, Name= "Dave" } ); } 

E ‘anche ansible e se sì, quale sarebbe il tipo di ritorno? So che non è una stringa ..

L’object che si restituisce ha una class, ma è anonimo quindi non è ansible specificarlo nel codice. Devi solo restituirlo come riferimento a un object :

 public object Test() { return new { ID = 5, Name= "Dave" }; } 

Si noti che il tipo anonimo è sconosciuto al di fuori dell’ambito del metodo, quindi la riflessione è l’unico modo per accedere alle sue proprietà.

Se vuoi essere in grado di usare convenientemente l’object restituito, devi dichiarare una class:

 public class TestResult { public int ID { get; set; } public string Name { get; set; } } public TestResult Test() { return new TestResult() { ID = 5, Name= "Dave" }; } 

Un’altra alternativa è usare una class esistente, se adatta al tuo scopo. Un KeyValuePair è vicino a quello che si utilizza, ma le proprietà saranno ovviamente denominate Key e Value anziché ID e Name :

 public KeyValuePair Test() { return new KeyValuePair(5, "Dave"); } 

Come altri hanno già detto, la cosa migliore da fare qui è creare un tipo nominale. Suggerirei che il tipo nominale abbia le stesse caratteristiche di un tipo anonimo; cioè, dovresti considerare di rendere il tipo immutabile e considerare di farlo esibire equità di valore .

È ansible restituire un tipo anonimo come object e quindi utilizzare l’istanza restituita altrove utilizzando una varietà di tecniche subdole. È ansible eseguire il cast dell’object su “dynamic” (in C # 4) e quindi utilizzare le proprietà del tipo anonimo, ma questo è lento e manca il controllo del tipo in fase di compilazione.

Puoi anche utilizzare il trucco “cast by example”, che ti consente di eseguire il controllo del tipo in fase di compilazione. Tuttavia, quel trucco funziona solo quando l’object di origine anonimo e l’object di esempio anonimo provengono dallo stesso assembly .

 static T CastByExample(object source, T example) where T : class { return source as T; } static object ReturnsAnonymous() { return new { X = 123 }; } static void DoIt() { object obj = ReturnsAnonymous(); var example = new { X = 0 }; var anon = CastByExample(obj, example); Console.WriteLine(anon.X); // 123 } 

Guarda come è subdolo? Usiamo l’inferenza del tipo di metodo e l’inferenza del tipo di variabile locale per dire al compilatore “queste due cose sono dello stesso tipo”. Ciò ti consente di esportare un tipo anonimo come object e di ricondurlo al tipo anonimo.

Ma probabilmente non dovresti farlo; se stai ricorrendo a trucchi così subdoli, dovresti semplicemente definire un tipo nominale in primo luogo. Inoltre, come ho detto, il trucco funziona solo se l’ esempio e gli oggetti sorgente sono stati creati in codice nello stesso assembly; due tipi anonimi “identici” in due gruppi diversi non si uniscono per essere dello stesso tipo.

Questo non è ansible in quanto la class anonima è valida solo nel contesto corrente. Se devi restituire un object, dovrai creare una vera class.

Suppongo che tu abbia lasciato la string come tipo di ritorno per sbaglio.

Anonymous type sono di class derivati ​​direttamente object .

Puoi restituirlo dal metodo come object come tipo di ritorno. Dai un’occhiata a questo .

No, non è ansible. Le tue opzioni sono:

  1. Definire una class reale per il valore di ritorno,
  2. Usa System.Tuple, o
  3. Parametri di utilizzo (probabilmente l’opzione meno valida).

Puoi fare una struct (o class) per questo.

 public struct IdAndName { public int Id; public string Name; public IdAndName(int id, string name) { ID = id; Name = name; } } 

Si potrebbe anche usare una Tupla , (ma ciò non è raccomandato in quanto le proprietà non sono nominate.

 class NewString { public int ID { get; set; } public string Name { get; set; } } public NewString Test() { return ( new NewString() { ID = 5, Name = "Dave" } ); } 

🙂