Convert.ChangeType()
ne gère pas correctement les types nullable ou les énumérations dans .NET 2.0 BCL (je pense que c'est corrigé pour BCL 4.0 cependant). Plutôt que de rendre l'implémentation externe plus complexe, faites en sorte que le convertisseur fasse plus de travail pour vous. Voici une implémentation que j'utilise :
public static class Converter
{
public static T ConvertTo(object value)
{
return ConvertTo(value, default(T));
}
public static T ConvertTo(object value, T defaultValue)
{
if (value == DBNull.Value)
{
return defaultValue;
}
return (T) ChangeType(value, typeof(T));
}
public static object ChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
throw new ArgumentNullException("conversionType");
}
// si ce n'est pas un type nullable, passez simplement les paramètres à Convert.ChangeType
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
// une valeur null entraîne une sortie nulle quel que soit le type de base
if (value == null)
{
return null;
}
// c'est un type nullable, et non null, ce qui signifie qu'il peut être converti en son type sous-jacent,
// donc écrasez le type de conversion passé avec ce type sous-jacent
conversionType = Nullable.GetUnderlyingType(conversionType);
}
else if (conversionType.IsEnum)
{
// les chaînes nécessitent la méthode Parse
if (value is string)
{
return Enum.Parse(conversionType, (string) value);
}
// les types primitifs peuvent être instanciés en utilisant ToObject
else if (value is int || value is uint || value is short || value is ushort ||
value is byte || value is sbyte || value is long || value is ulong)
{
return Enum.ToObject(conversionType, value);
}
else
{
throw new ArgumentException(String.Format("La valeur ne peut pas être convertie en {0} - le type actuel n'est " +
"pas pris en charge pour les conversions d'énumération.", conversionType.FullName));
}
}
return Convert.ChangeType(value, conversionType);
}
}
Ensuite, votre implémentation de GetQueryString peut être :
public static T GetQueryString(string key)
{
T result = default(T);
string value = HttpContext.Current.Request.QueryString[key];
if (!String.IsNullOrEmpty(value))
{
try
{
result = Converter.ConvertTo(value);
}
catch
{
//Impossible de convertir. Renvoie la valeur par défaut...
result = default(T);
}
}
return result;
}