Установить свойство Nullable <> отражением
Я пытаюсь установить свойство Nullable < > динамически.
Получаю свое свойство ex:
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 < > Generic. Поэтому я пытаюсь найти способ установить мое свойство.
Чтобы узнать тип моего свойства nullable < > i, выполните
Nullable.GetUnderlyingType(property.PropertyType)
Любая идея?
-
Я пытаюсь создать экземпляр моего свойства Nullable < > с помощью
var nullVar = Activator.CreateInstance(typeof (Nullable < > ). MakeGenericType (новый тип [] {Nullable.GetUnderlyingType(свойство .PropertyType)}));
Но nullVar всегда Null
Ответы
Ответ 1
Если вы хотите преобразовать произвольную строку в базовый тип 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. Предостережение: это не быстрый код.
Ответ 2
Если это nullable int, вам нужно использовать параметр int, а не строку.
property.SetValue(klass,1256,null);
Обратите внимание на изменение класса, а не класса, поскольку класс является зарезервированным ключевым словом. Вы также можете использовать @class, если это абсолютно необходимо (цитируя его).
Если ваше свойство является общим, тогда, я думаю, вам, вероятно, понадобится использовать Convert для преобразования того, что у вас есть, что вам нужно.
var nullType = Nullable.GetUnderlyingType(property.PropertyType)
var value = Convert.ChangeType("1256", nullType );
property.SetValue(klass, value, null );
Ответ 3
Вот полный пример, показывающий, как это сделать:
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<>
.
Ответ 4
"1256"
- это строка, а не int.
Ответ 5
Я столкнулся с этой же проблемой, а также с проблемой с Convert.ChangeType, которая не обрабатывает DateTimes на Nullables, поэтому я объединил пару решений stackoverflow с некоторой динамической магией .NET 4, чтобы получить что-то, что я думаю, немного сладкое. Если вы посмотрите на код, мы используем dynamic для ввода объекта в Nullable во время выполнения, тогда время выполнения рассматривает его по-разному и позволяет присвоения базового типа объекту с нулевым значением.
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);
}
}
}
Ответ 6
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);
}