c# - ser - ¿Cómo hago que el tipo de devolución de un método sea genérico?
no se permiten restricciones en declaraciones no genericas (4)
¿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.
public static string ConfigSetting(string settingName)
{
return ConfigurationManager.AppSettings[settingName];
}
Debes hacerlo un método genérico, como este:
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. Entonces, podría utilizar 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 del todo convencido de que todo esto sea una buena idea, fíjate ...
Hay muchas maneras de hacerlo (enumeradas por prioridad, específicas para el problema del PO)
Opción 1: enfoque directo: cree funciones múltiples para cada tipo que espere en lugar de tener una función genérica.
public static bool ConfigSettingInt(string settingName) { return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]); }
Opción 2: cuando no desee utilizar métodos sofisticados de conversión : envíe el valor al objeto 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 lanzamiento no es válido (su caso). No recomendaría hacer esto si no está seguro del tipo de conversión, más bien vaya a la opción 3.
Opción 3: Genérico con seguridad de tipo : cree una función genérica para manejar la conversión de tipo.
public static T ConvertValue<T,U>(U value) where U : IConvertible { return (T)Convert.ChangeType(value, typeof(T)); }
Nota: T es el tipo esperado, observe la restricción where aquí (el tipo de U debe ser IConvertible para salvarnos de los errores)
Podría usar Convert.ChangeType()
:
public static T ConfigSetting<T>(string settingName)
{
return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T));
}
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.