文字列値で反射してプロパティを設定します
-
23-08-2019 - |
質問
私はタイプstring
の値は、リフレクションを通じてオブジェクトのプロパティを設定したいと思います。
ですから、例えば、私はShip
あるLatitude
の性質と、double
クラスがあるとします。
ここで私が何をしたいものです。
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, value, null);
のようになり、これはArgumentException
をスローします:
型 '可能System.String' のオブジェクトは 'System.Double' 型に変換できない。
私はpropertyInfo
に基づいて、適切な型に値を変換できますか?
解決
あなたは使用することができます Convert.ChangeType()
に - それはあなたがランタイム情報を使用することができますあらゆるIConvertible
タイプに表現形式を変更します。いないすべての変換は、しかし、可能であり、そしてあなたがIConvertible
ない型からの変換をサポートしたい場合は特殊なケースロジックを記述する必要があります。
(例外処理や特殊ケースロジックなしで)対応するコードは次のようになります。
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
他のヒント
他のいくつかは、あなたがConvert.ChangeType
を使用したい、と述べてきたようにます:
propertyInfo.SetValue(ship,
Convert.ChangeType(value, propertyInfo.PropertyType),
null);
実際には、私はあなたが全体の Convert
クラス>。
このクラス、および他の多くの便利なクラスは、/ < System
名前空間の一部でありますA>。私はそれが便利な私が見逃している機能を表示するために、毎年かそこらその名前空間をスキャンするために見つけます。それを試してみる!
Convert.ChangeType
の受信を開始しますnullable
型を含む始めるといくつかのケースのための作業を行います - 私はInvalidCastExceptions
多くの人が推奨されて気づきます
ラッパーがこれを処理するために数年前に書かれたが、それはどちらか完璧ではありません。
あなたは型コンバータ(エラーチェック)を使用することができます:
Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
のコードを組織の面では、を作成することができますこのようなコードにつながるミックスインする-の種類:
Ship ship = new Ship();
ship.SetPropertyAsString("Latitude", "5.5");
この本のコードで実現することになります。
public interface MPropertyAsStringSettable { }
public static class PropertyAsStringSettable {
public static void SetPropertyAsString(
this MPropertyAsStringSettable self, string propertyName, string value) {
var property = TypeDescriptor.GetProperties(self)[propertyName];
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
}
}
public class Ship : MPropertyAsStringSettable {
public double Latitude { get; set; }
// ...
}
MPropertyAsStringSettable
は、多くの異なるクラスのために再利用することができます。
また、独自のカスタムを作成することができます型コンバータを接続するを
:あなたの特性やクラスへpublic class Ship : MPropertyAsStringSettable {
public Latitude Latitude { get; set; }
// ...
}
[TypeConverter(typeof(LatitudeConverter))]
public class Latitude { ... }
私はのLBushkinのからの回答を試してみましたが、それは素晴らしい仕事、それはNULL値とNULL可能フィールドに対しては機能しません。だから私はこれにそれを変更しました。
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);
}
あなたはおそらく Convert.ChangeType
の方法を探しています。たとえばます:
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
Convert.ChangeType
を使用してPropertyInfo.PropertyType
から変換するタイプを取得します。
propertyInfo.SetValue( ship,
Convert.ChangeType( value, propertyInfo.PropertyType ),
null );
私は一般的な答えでこれにお答えします。通常、これらの答えは、GUIDをして働いていません。ここでのGUIDを持つ作業バージョンもあります。
var stringVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as string 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(stringVal);
それとも、試みることができる:
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);
//But this will cause problems if your string value IsNullOrEmplty...
あなたがメトロアプリを書いている場合は、他のコードを使用する必要があります:
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType));
注:
ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
の代わりに
ship.GetType().GetProperty("Latitude");
次のコードを使用すると、あなたの問題を解決する必要があります:
item.SetProperty(prop.Name, Convert.ChangeType(item.GetProperty(prop.Name).ToString().Trim(), prop.PropertyType));
あなたは、リフレクションで遊ぶために見ているか、ソフトウェアの生産ピースを構築するために探していますか?私はあなたがプロパティを設定するためにリフレクションを使用している理由を問う考えます。
Double new_latitude;
Double.TryParse (value, out new_latitude);
ship.Latitude = new_latitude;