2012-03-21 18 views
108

¿Hay alguna manera de hacer que este método sea genérico para que pueda devolver una cadena, bool, int o double? En este momento, está devolviendo una cadena, pero si puede encontrar "verdadero" o "falso" como valor de configuración, me gustaría devolver un bool, por ejemplo.¿Cómo hago que el tipo de devolución de un método sea genérico?

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

¿Hay una manera para que usted sepa ¿Qué tipo de configuración es cada? – thecoshman

+2

Creo que la pregunta que realmente desea hacer es "¿Cómo hago que la configuración de mi aplicación sea fuertemente tipada?" Sin embargo, ha pasado demasiado tiempo desde que trabajé con eso para escribir una respuesta adecuada. – Simon

+0

Yah, idealmente no quiero tener que pasar el tipo en el método. Solo tendré los 4 tipos que mencioné. Entonces, si se establece "verdadero"/"falso", quiero que esta función devuelva un valor booleano (sin necesidad de pasarlo al método), probablemente pueda combinar int y double en solo el doble, y todo lo demás debería ser una cadena. Lo que se responde ya funcionará bien, pero necesito pasar el tipo cada vez, lo cual probablemente sea correcto. – MacGyver

Respuesta

234

Usted necesita para que sea un método genérico, como esto:

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

Pero la persona que llama tendrá que especificar el tipo que esperan. A continuación, podría usar potencialmente Convert.ChangeType, suponiendo que todos los tipos relevantes son compatibles:

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

No estoy totalmente convencido de que todo esto es una buena idea, que conste ...

+10

/* código para convertir la configuración en T ... */y aquí sigue toda la novela :) –

+1

¿No es necesario que conozca el tipo de configuración que desea obtener, que puede no ser posible. – thecoshman

+0

@thecoshman: Bueno, el OP * solicitó * un método genérico, así que eso es lo que he dado, pero con la advertencia de que la persona que llama * necesitará * saber el tipo pertinente. –

20

se podía utilizar 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; 
    } 

estaba realizando esto a lo largo de mi código y quería una forma de ponerlo en un método. Quería compartir esto aquí porque no tenía que usar Convert.ChangeType para mi valor de retorno. Esto puede no ser una mejor práctica, pero funcionó para mí. Este método toma una matriz de tipo genérico y un valor para agregar al final de la matriz. La matriz se copia con el primer valor eliminado y el valor tomado en el método se agrega al final de la matriz. Lo último es que devuelvo el conjunto genérico.

0

Hay muchas maneras de hacer esto (enumerados por orden de prioridad, específicos para el problema de la OP)

  1. Opción 1/aproximación directa - Crear múltiples funciones para cada tipo que se pueden esperar en lugar de tener uno genérico función.

    public static bool ConfigSettingInt(string settingName) 
    { 
        return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]); 
    } 
    
  2. Opción 2/Cuando no se desea utilizar métodos de fantasía de conversión - Reparto del valor de oponerse y luego al tipo genérico.

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

    Nota - Esto generará un error si el yeso no es válido (su caso). Yo no recomiendo hacer esto si no está seguro sobre el tipo de fundición, en lugar de ir a la opción 3.

  3. Opción 3/genérico con seguridad de tipos - Crear una función genérica para manejar la conversión de tipos.

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

    Nota - T es el tipo esperado, tenga en cuenta la restricción en donde aquí (tipo de U debe ser IConvertible para salvarnos de los errores)

+0

¿Por qué hacer la tercera opción genérica en 'U'? No tiene sentido hacerlo, y hace que el método sea más difícil de llamar. Solo acepta 'IConvertible' en su lugar. No creo que valga la pena incluir la segunda opción para esta pregunta dado que no responde la pregunta que se hace. Probablemente también deba cambiar el nombre del método en la primera opción ... –

Cuestiones relacionadas