2012-03-21 6 views
108

C'è un modo per rendere questo metodo generico in modo da poter restituire una stringa, bool, int o double? In questo momento, restituisce una stringa, ma se è in grado di trovare "true" o "false" come valore di configurazione, mi piacerebbe restituire un bool, ad esempio.Come si rende generico il tipo di restituzione di un metodo?

public static string ConfigSetting(string settingName) 
    { 
     return ConfigurationManager.AppSettings[settingName]; 
    } 
+0

Esiste un modo per voi di sapere che tipo è ogni impostazione? – thecoshman

+2

Penso che la domanda che vuoi veramente porre sia "Come faccio a configurare fortemente la mia configurazione dell'applicazione?" È passato troppo tempo da quando ho lavorato con quello per scrivere una risposta adeguata, però. – Simon

+0

Yah, idealmente non voglio dover passare il tipo al metodo. Avrò solo i 4 tipi che ho menzionato. Quindi se "true"/"false" è impostato, voglio che questa funzione restituisca un valore booleano (senza doverlo passare nel metodo), probabilmente posso combinare int e double in solo double, e tutto il resto dovrebbe essere una stringa. Ciò che viene risposto già funzionerà bene, ma ho bisogno di passare il tipo ogni volta, che probabilmente sta bene. – MacGyver

risposta

234

è necessario effettuare un metodo generico, in questo modo:

public static T ConfigSetting<T>(string settingName) 
{ 
    return /* code to convert the setting to T... */ 
} 

Ma la chiamante dovrà specificare il tipo che si aspettano. Si potrebbe quindi potenzialmente usare Convert.ChangeType, partendo dal presupposto che tutti i tipi rilevanti sono supportati:

public static T ConfigSetting<T>(string settingName) 
{ 
    object value = ConfigurationManager.AppSettings[settingName]; 
    return (T) Convert.ChangeType(value, typeof(T)); 
} 

Io non sono del tutto convinto che tutto questo è una buona idea, si badi bene ...

+10

/* codice per convertire l'impostazione in T ... */e qui segue l'intero romanzo :) –

+1

Questo non richiede di conoscere il tipo di impostazione che si desidera ottenere, il che potrebbe non essere possibile. – thecoshman

+0

@thecoshman: beh, l'OP * ha richiesto * un metodo generico, quindi è quello che ho dato, ma con un avvertimento che il chiamante * dovrà * conoscere il tipo pertinente. –

20

Si potrebbe utilizzare Convert.ChangeType() :

public static T ConfigSetting<T>(string settingName) 
{ 
    return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T)); 
} 
-1
private static T[] prepareArray<T>(T[] arrayToCopy, T value) 
    { 
     Array.Copy(arrayToCopy, 1, arrayToCopy, 0, arrayToCopy.Length - 1); 
     arrayToCopy[arrayToCopy.Length - 1] = value; 
     return (T[])arrayToCopy; 
    } 

stavo eseguendo questo tutto il mio codice e ha voluto un modo per metterlo in un metodo. Volevo condividere questo qui perché non dovevo usare Convert.ChangeType per il mio valore di ritorno. Questo potrebbe non essere una buona pratica, ma ha funzionato per me. Questo metodo utilizza una matrice di tipo generico e un valore da aggiungere alla fine dell'array. L'array viene quindi copiato con il primo valore stripped e il valore preso nel metodo viene aggiunto alla fine dell'array. L'ultima cosa è che restituisco l'array generico.

0

Ci sono molti modi di fare questo (elencati per priorità, specifici per il problema del PO)

  1. Opzione 1/approccio diritta - Creazione di più funzioni per ogni tipo che ci si aspetta piuttosto che avere una generica funzione.

    public static bool ConfigSettingInt(string settingName) 
    { 
        return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]); 
    } 
    
  2. Opzione 2/Quando non si desidera utilizzare i metodi di fantasia di conversione - il cast del valore di opporsi e poi al tipo generico.

    public static T ConfigSetting<T>(string settingName) 
    { 
        return (T)(object)ConfigurationManager.AppSettings[settingName]; 
    } 
    

    Nota - Questo genera un errore se il cast non è valido (il tuo caso). Non consiglierei di fare questo se non si è sicuri del tipo di fusione, piuttosto andare per l'opzione 3.

  3. Opzione 3/generico con la sicurezza di tipo - Creare una funzione generica per gestire la conversione del tipo.

    public static T ConvertValue<T,U>(U value) where U : IConvertible 
    { 
        return (T)Convert.ChangeType(value, typeof(T)); 
    } 
    

    Nota - T è il tipo previsto, nota il vincolo in cui qui (tipo di U deve essere IConvertible per salvarci dagli errori)

+0

Perché rendere la terza opzione generica in 'U'? Non ha senso farlo e rende il metodo più difficile da chiamare. Accetta invece 'IConvertible'. Non penso che valga la pena includere la seconda opzione per questa domanda dato che non risponde alla domanda che viene posta. Probabilmente dovresti anche rinominare il metodo nella prima opzione ... –

Problemi correlati