質問

私はタイプ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>。私はそれが便利な私が見逃している機能を表示するために、毎年かそこらその名前空間をスキャンするために見つけます。それを試してみる!

あなたは型コンバータ(エラーチェック)を使用することができます:

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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top