12

Nullable<> プロパティを動的に設定しようとしています。

私は自分の財産を取得します例:

PropertyInfo property = class.GetProperty("PropertyName"); // My property is Nullable<> at this time So the type could be a string or int

次のようなリフレクションでプロパティを設定したい

property.SetValue(class,"1256",null);

プロパティが Nullable<> ジェネリックの場合、機能しません。だから私は私の財産を設定する方法を見つけようとします。

私の nullable<> プロパティのタイプを知るために、私は実行します

Nullable.GetUnderlyingType(property.PropertyType)

何か案が ?

  • Nullable<> プロパティのインスタンスを作成しようとしています

    var nullVar = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(new Type[] { Nullable.GetUnderlyingType(property.PropertyType) }));

ただし、nullVar は常に Null です

4

6 に答える 6

17

任意の文字列を Nullable の基になる型に変換する場合は、Convert クラスを使用できます。

var propertyInfo = typeof(Foo).GetProperty("Bar");
object convertedValue = null;
try 
{ 
    convertedValue = System.Convert.ChangeType("1256", 
        Nullable.GetUnderlyingType(propertyInfo.PropertyType));
} 
catch (InvalidCastException)
{
    // the input string could not be converted to the target type - abort
    return;
}
propertyInfo.SetValue(fooInstance, convertedValue, null);

この例は、ターゲットの型が int、short、long (または、入力文字列が負でない数値を表すため、符号なしバリアント)、double、float、または decimal の場合に機能します。注意: これは高速なコードではありません。

于 2009-09-28T19:02:46.253 に答える
9

null 許容の int の場合は、文字列ではなく int パラメーターを使用する必要があります。

 property.SetValue(klass,1256,null);

class は予約済みのキーワードであるため、class ではなく klass に変更されていることに注意してください。絶対に必要な場合は @class を使用することもできます (引用)。

プロパティがジェネリックである場合は、おそらく Convert を使用して、必要なものを必要なものに変換する必要があると思います。

 var nullType = Nullable.GetUnderlyingType(property.PropertyType)
 var value = Convert.ChangeType("1256", nullType );
 property.SetValue(klass, value, null );
于 2009-09-28T18:50:34.453 に答える
5

これを行う方法を示す完全な例を次に示します。

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        Foo foo = new Foo();
        typeof(Foo).GetProperty("Bar")
            .SetValue(foo, 1234, null);
    }
}

class Foo
{
    public Nullable<Int32> Bar { get; set; }
}

他の人が述べたように、正しい型を関数に渡す必要がありSetValueますが、他のリフレクション コードも正しくありません。メンバーを照会する前に、問題のクラスの型を取得する必要があります。

編集:私が正しく理解している場合、リフレクションを介して任意のプロパティに文字列値を設定しようとしています。これを行うには、型検査と型変換を行う必要があります。

これが私が意味することの例です:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        Foo foo = new Foo();

        PropertyInfo property = typeof(Foo).GetProperty("Bar");
        Object value =
            Convert.ChangeType("1234",
                Nullable.GetUnderlyingType(property.PropertyType)
                ?? property.PropertyType);

        property.SetValue(foo, value, null);
    }
}

class Foo
{
    public Nullable<Int32> Bar { get; set; }
}

このアプローチは、プロパティが であるかどうかに関係なく安全に使用できますNullable<>

于 2009-09-28T18:53:14.167 に答える
3

これと同じ問題に加えて、Convert.ChangeType が Nullable で DateTimes を処理しないという問題にも遭遇したので、いくつかのスタック オーバーフロー ソリューションと .NET 4 の動的マジックを組み合わせて、ちょっといいと思うものを取得しました。コードを見ると、実行時に dynamic を使用してオブジェクトを Nullable に型指定すると、実行時に別の方法で処理され、基本型を null 許容オブジェクトに割り当てることができます。

public void GenericMapField(object targetObj, string fieldName, object fieldValue)
{
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName);
    if (prop != null)
    {
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            dynamic objValue = System.Activator.CreateInstance(prop.PropertyType);
            objValue = fieldValue;
            prop.SetValue(targetObj, (object)objValue, null);
        }
        else
        {
            prop.SetValue(targetObj, fieldValue, null);
        }
    }
}
于 2011-10-26T10:55:12.497 に答える
2

"1256"int ではなく文字列です。

于 2009-09-28T18:51:04.770 に答える
1
public static void SetValue(object target, string propertyName, object value)
{
  if (target == null)
    return;

  PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);

  object convertedValue = value;
  if (value != null && value.GetType() != propertyInfo.PropertyType)
  {
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
    convertedValue = Convert.ChangeType(value, propertyType);
  }

  propertyInfo.SetValue(target, convertedValue, null);
}
于 2014-04-26T07:57:37.430 に答える