2008-12-26 6 views
31

Je le code suivant:fonction de conversion générique ne semble pas fonctionner avec Guids

public static T ParameterFetchValue<T>(string parameterKey) 
{ 
    Parameter result = null; 

    result = ParameterRepository.FetchParameter(parameterKey); 

    return (T)Convert.ChangeType(result.CurrentValue, typeof(T), CultureInfo.InvariantCulture); 
} 

Le type de result.CurrentValue est une chaîne. Je voudrais être en mesure de le convertir en Guid mais je continue à obtenir l'erreur:

Invalid cast from System.String to System.Guid

Cela fonctionne parfaitement avec les types de données primitifs.
Est-il possible de faire ce travail pour pour les types de données non-primitifs?

Répondre

82

Que diriez-vous:

T t = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(text); 

fonctionne bien pour Guid et la plupart des autres types.

+4

Soyez prudent avec l'utilisation ConvertFromInvariantString. Si votre type est un DateTime et que vous avez des formats de date internationaux, cela va exploser. Je viens de retrouver un bug très difficile à trouver basé sur cette réponse. –

+0

@DPeden en effet, ils doivent correspondre - mon utilisation ici utilisait invariant dans l'hypothèse que les données sérialisées devraient généralement être dans un format invariable –

+0

Oui, d'accord. J'ai toujours voté pour votre réponse car c'est très utile. Juste en soulignant ce potentiel obtenu pour les autres comme il m'a brûlé. –

0

Essayez ceci:

public object ChangeType(object value, Type type) 
    { 
     if (value == null && type.IsGenericType) return Activator.CreateInstance(type); 
     if (value == null) return null; 
     if (type == value.GetType()) return value; 
     if (type.IsEnum) 
     { 
      if (value is string) 
       return Enum.Parse(type, value as string); 
      else 
       return Enum.ToObject(type, value); 
     } 
     if (!type.IsInterface && type.IsGenericType) 
     { 
      Type innerType = type.GetGenericArguments()[0]; 
      object innerValue = ChangeType(value, innerType); 
      return Activator.CreateInstance(type, new object[] { innerValue }); 
     } 
     if (value is string && type == typeof(Guid)) return new Guid(value as string); 
     if (value is string && type == typeof(Version)) return new Version(value as string); 
     if (!(value is IConvertible)) return value; 
     return Convert.ChangeType(value, type); 
    } 
Questions connexes