2016-01-14 11 views
6

Ho esaminato molte domande simili a questa, ma nessuna di esse ha realmente toccato ciò che voglio esattamente fare. Quello che sto cercando di fare è leggere da una fonte esterna un elenco di variabili che includono anche il loro tipo di dati in un array di stringhe:Metodo con più tipi di reso

Esempio:

ID/Key  Type Value/Data; 
varName1 bool true; 
varName2 string str; 
varName3 int  5; 

Ho quindi memorizzare questi sono oggetti in un dizionario come oggetti contenenti più stringhe, con l'ID che funge anche da chiave.

Quello che voglio fare è ora creare un metodo che utilizza un'istruzione switch che inserisce la stringa nel tipo di dati corretto e la restituisce senza dover specificare nulla nella chiamata al metodo. La funzione dovrebbe essere simile a questo:

public ??? Method(string key) 
{ 
    if(dictionary.ContainsKey(ID)) 
    { 
     Var temp = dictionary[ID]; 

     switch (temp.Type) 
     { 
      case "bool": 
       return Convert.ToBoolean(temp.Value); 

      case "int" 
       return Convert.ToInt(temp.Value); 

      case "string" 
       return temp.Value; 
     } 
    } 

    return "NULL"; 
} 

La chiamata al metodo dovrebbe essere simile a questa:

int x = Method(string key); 
string word = Method(string key); 
boolean isTrue = Method(string key); 

Forse ho perso qualcosa, ma devo ancora trovare qualcosa che fa davvero qualcosa di molto come questo. Ogni pensiero su questo è ben accetto.

+2

Scusate, niente di simile in C#. Un metodo ha un tipo di reso fisso. Potresti usare 'object' come tipo di ritorno, ma dovresti eseguire il cast. – adv12

+1

Dovresti rendere il metodo generico per farlo funzionare. E finirà per apparire come 'stringa parola = Metodo (chiave)' quando lo hai usato. Inoltre dovresti fare 'bool?' E 'int?dal momento che si desidera restituire 'null' quando la chiave non viene trovata. – juharr

+0

Se i tuoi valori sono stati memorizzati come 'Object', potresti fare' (T) value'. Che cosa ti impedisce di stringere 'string word = (string) Method (string key);', restituito, metodo restituisce 'object' –

risposta

6

Il compilatore non ha modo di distinguere tra le tre chiamate di metodo che ci hai fornito, perché tutti sembrano Method(key);

Una possibilità è quella di restituire un object e poi aspettarsi che il codice di consumo per buttarlo a quello che vogliono:

public object Method(string key) 
{ 
    if(dictionary.ContainsKey(key)) 
    { 
     var temp = dictionary[key]; 

     switch (temp.Type) 
     { 
      case "bool": 
       return Convert.ToBoolean(temp.Value); 

      case "int" 
       return Convert.ToInt(temp.Value); 

      case "string" 
       return temp.Value; 
     } 
    } 

    return "NULL"; 
} 

... 

int x = (int) Method(key); 
string word = (string) Method(key); 
bool isTrue = (bool) Method(key); 

si potrebbe anche utilizzare la parola chiave dynamic per fare il cast implicito:

public dynamic Method(string key) 
{ 
    if(dictionary.ContainsKey(key)) 
    { 
     var temp = dictionary[key]; 

     switch (temp.Type) 
     { 
      case "bool": 
       return Convert.ToBoolean(temp.Value); 

      case "int" 
       return Convert.ToInt(temp.Value); 

      case "string" 
       return temp.Value; 
     } 
    } 

    return "NULL"; 
} 

... 

int x = Method(key); 
string word = Method(key); 
bool isTrue = Method(key); 

Tuttavia, dynamic è un concetto molto potente, ed è facile per lui sfuggire di mano, quindi devi essere molto attento a questo.

Mi sembra che ti aspetti che il tuo codice chiamante sappia quale tipo di oggetto è previsto per ogni chiave. Sembra che forse l'approccio migliore è quello di lasciare solo la fornitura all'utente che le informazioni:

public T Method<T>(string key) 
{ 
    if(dictionary.ContainsKey(key)) 
     return (T) Convert.ChangeType(dictionary[key].Value, typeof(T)); 
    return default(T); 
} 

... 

int x = Method<int>(key); 
string word = Method<string>(key); 
bool isTrue = Method<bool>(key); 

In questo modo, non c'è bisogno di monitorare il valore di tipo di oggetti del dizionario, in primo luogo.

+1

Mi rendo conto che l'OP ha usato' booleano', ma in C# è 'bool' o' Boolean'. – juharr

+0

@juharr: Giusto, grazie. – StriplingWarrior

+0

Allo stesso modo da OP, 'Var' non è valido in C#, dovrebbe essere' var'. –

0

Il tipo di ritorno di una funzione deve essere digitato. Come con qualsiasi altra variabile o operazione, qualsiasi tipo che eredita dal tipo specificato è un valore di ritorno valido (motivo per cui l'oggetto consente qualsiasi cosa come valore).

Personalmente io non credo che sia utile fare un metodo con più tipi di ritorno, ma se si vuole veramente avere un metodo con più tipi di ritorno, è possibile utilizzare il tipo di dynamic in .NET 4.0:

private static void Main(string[] args) 
    { 
     int x = Method("varName3"); 
     string word = Method("varName2"); 
     bool isTrue = Method("varName1"); 
    } 

    private static dynamic Method(string key) 
    { 
     var dictionary = new Dictionary<string, KeyValuePair<Type, object>>() 
     { 
      { "varName1", new KeyValuePair<Type, object>(typeof(bool), false) }, 
      { "varName2", new KeyValuePair<Type, object>(typeof(string), "str") }, 
      { "varName3", new KeyValuePair<Type, object>(typeof(int), 5) }, 
     }; 

     if (dictionary.ContainsKey(key)) 
     { 
      return dictionary[key].Value; 
     } 

     return null; 
    } 

Spero che sia utile

+0

Aiutato meravigliosamente, ma purtroppo sono limitato al framework 3.5. Background: questo è uno strumento per le persone che usano Unity. –

+0

Se si è limitati a .NET 3.5, proverei a rendere il metodo generico: int x = Metodo ("varName3"); Per favore dai un'occhiata alla risposta di StriplingWarrior. – Sneijder

Problemi correlati