Définition d’une propriété par reflection avec une valeur de chaîne

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 :

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx

Un wrapper a été écrit il y a quelques années pour gérer cela, mais ce n’est pas parfait non plus.

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx

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;