341

type の値で、リフレクションを介してオブジェクトのプロパティを設定したいと思います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ですか?

4

12 に答える 12

569

使用できます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);
于 2009-07-06T20:44:59.807 に答える
35

他の何人かが言ったように、あなたは使いたいConvert.ChangeType

propertyInfo.SetValue(ship,
    Convert.ChangeType(value, propertyInfo.PropertyType),
    null);

Convert実際、 Class全体を見ることをお勧めします。

このクラス、および他の多くの便利なクラスはSystemNamespaceの一部です。その名前空間を毎年かそこらスキャンして、見逃している機能を確認すると便利です。試してみる!

于 2009-07-06T20:44:54.237 に答える
22

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);
}
于 2017-01-04T14:51:33.453 に答える
20

多くの人が推奨していることに気付きましたConvert.ChangeType- これはいくつかのケースではうまくいきnullableますが、型を使い始めるとすぐに次のようなものを受け取り始めますInvalidCastExceptions:

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

これを処理するラッパーが数年前に作成されましたが、それも完璧ではありません。

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

于 2010-08-13T11:08:06.367 に答える
12

型コンバーターを使用できます (エラー チェックなし)。

Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);

コードを整理するという点では、次のようなコードになる一種の mixinを作成できます。

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 { ... }
于 2010-09-13T13:51:17.240 に答える
6

あなたはおそらくその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);
于 2009-07-06T20:48:30.703 に答える
5

Convert.ChangeTypeから変換する型を使用および取得しPropertyInfo.PropertyTypeます。

propertyInfo.SetValue( ship,
                       Convert.ChangeType( value, propertyInfo.PropertyType ),
                       null );
于 2009-07-06T20:48:48.317 に答える
3

または、次のことを試すことができます。

propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);

//But this will cause problems if your string value IsNullOrEmplty...
于 2009-07-06T20:47:37.507 に答える
0

次のコードを使用すると、問題が解決するはずです。

item.SetProperty(prop.Name, Convert.ChangeType(item.GetProperty(prop.Name).ToString().Trim(), prop.PropertyType));
于 2019-06-03T10:16:25.613 に答える
-11

Reflection をいじってみたいですか、それとも製品版のソフトウェアを構築しようとしていますか? プロパティを設定するためにリフレクションを使用している理由を疑問に思います。

Double new_latitude;

Double.TryParse (value, out new_latitude);
ship.Latitude = new_latitude;
于 2009-07-06T20:57:55.787 に答える