Je voudrais définir une propriété d’un object via Reflection, avec une valeur de type ssortingng
. Par exemple, supposons que je possède une classe Ship
, avec une propriété de Latitude
, qui est un double
.
Voici ce que j’aimerais faire:
Ship ship = new Ship(); ssortingng value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, value, null);
Tel quel, cela génère une ArgumentException
:
L’object de type ‘System.Ssortingng’ ne peut pas être converti en type ‘System.Double’.
Comment puis-je convertir la valeur au type approprié, en fonction de propertyInfo
?
Vous pouvez utiliser Convert.ChangeType()
– Il vous permet d’utiliser les informations d’exécution sur n’importe IConvertible
type IConvertible
pour modifier les formats de représentation. Cependant, toutes les conversions ne sont pas possibles et vous devrez peut-être écrire une logique de cas particulier si vous souhaitez prendre en charge les conversions à partir de types non IConvertible
.
Le code correspondant (sans gestion des exceptions ou logique de cas particulier) serait:
Ship ship = new Ship(); ssortingng value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
Comme plusieurs autres l’ont dit, vous voulez utiliser Convert.ChangeType
:
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
En fait, je vous recommande de regarder l’ensemble de la classe Convert
.
Cette classe et de nombreuses autres classes utiles font partie de l’ espace de noms System
. Je trouve utile d’parsingr chaque année cet espace de noms pour voir les fonctionnalités que j’ai manquées. Essaie!
Je remarque que de nombreuses personnes recommandent Convert.ChangeType
– Cela fonctionne dans certains cas, mais dès que vous commencerez à impliquer des types InvalidCastExceptions
vous commencerez à recevoir des InvalidCastExceptions
:
Un wrapper a été écrit il y a quelques années pour gérer cela, mais ce n’est pas parfait non plus.
Vous pouvez utiliser un convertisseur de type (pas de vérification d’erreur):
Ship ship = new Ship(); ssortingng value = "5.5"; var property = ship.GetType().GetProperty("Latitude"); var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue);
En termes d’organisation du code, vous pourriez créer un type de mixin qui aboutirait à un code comme celui-ci:
Ship ship = new Ship(); ship.SetPropertyAsSsortingng("Latitude", "5.5");
Cela serait réalisé avec ce code:
public interface MPropertyAsSsortingngSettable { } public static class PropertyAsSsortingngSettable { public static void SetPropertyAsSsortingng( this MPropertyAsSsortingngSettable self, ssortingng propertyName, ssortingng value) { var property = TypeDescriptor.GetProperties(self)[propertyName]; var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue); } } public class Ship : MPropertyAsSsortingngSettable { public double Latitude { get; set; } // ... }
MPropertyAsSsortingngSettable
peut être réutilisé pour de nombreuses classes différentes.
Vous pouvez également créer vos propres convertisseurs de types personnalisés à associer à vos propriétés ou classes:
public class Ship : MPropertyAsSsortingngSettable { public Latitude Latitude { get; set; } // ... } [TypeConverter(typeof(LatitudeConverter))] public class Latitude { ... }
Vous recherchez probablement la méthode Convert.ChangeType
. Par exemple:
Ship ship = new Ship(); ssortingng value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
Utiliser Convert.ChangeType
et obtenir le type à convertir à partir de PropertyInfo.PropertyType
.
propertyInfo.SetValue( ship, Convert.ChangeType( value, propertyInfo.PropertyType ), null );
J’ai essayé la réponse de LBushkin et cela a fonctionné très bien, mais cela ne fonctionnera pas pour les valeurs NULL et les champs nullables. Donc je l’ai changé pour ceci:
propertyName= "Latitude"; PropertyInfo propertyInfo = ship.GetType().GetProperty(propertyName); if (propertyInfo != null) { Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; object safeValue = (value == null) ? null : Convert.ChangeType(value, t); propertyInfo.SetValue(ship, safeValue, null); }
Ou vous pourriez essayer:
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); //But this will cause problems if your ssortingng value IsNullOrEmplty...
Si vous écrivez une application Metro, vous devez utiliser un autre code:
Ship ship = new Ship(); ssortingng value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType));
Remarque:
ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
au lieu de
ship.GetType().GetProperty("Latitude");
Je vais répondre à cela avec une réponse générale. Habituellement, ces réponses ne fonctionnent pas avec les guides. Voici une version de travail avec des guides aussi.
var ssortingngVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as ssortingng to set var prop = obj.GetType().GetProperty("FooGuidProperty"); // property to be setted var propType = prop.PropertyType; // var will be type of guid here var valWithRealType = TypeDescriptor.GetConverter(propType).ConvertFrom(ssortingngVal);
Cherchez-vous à jouer avec Reflection ou cherchez-vous à créer un logiciel de production? Je me demande pourquoi vous utilisez la reflection pour définir une propriété.
Double new_latitude; Double.TryParse (value, out new_latitude); ship.Latitude = new_latitude;