Конвертировать в Type на лету в C # .NET - PullRequest
20 голосов
/ 01 октября 2011

Я хочу преобразовать объект в тип, который будет назначен во время выполнения.

Например, предположим, что у меня есть функция, которая присваивает строковое значение (от TextBox or Dropdownlist) Object.Property.

Как бы я преобразовал значение в правильный тип? Например, это может быть целое число, строка или перечисление.

Public void Foo(object obj,string propertyName,object value)
{
  //Getting type of the property og object.
  Type t= obj.GetType().GetProperty(propName).PropertyType;

  //Now Setting the property to the value .
  //But it raise an error,because sometimes type is int and value is "2"
  //or type is enum (e.a: Gender.Male) and value is "Male"
  //Suppose that always the cast is valid("2" can be converted to int 2)

  obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}

Ответы [ 5 ]

38 голосов
/ 01 октября 2011

Вам нужно использовать функцию Convert.ChangeType (...) (вход может быть просто объектом ... У меня только что была предварительно запеченная строковая версия):

/// <summary>
/// Sets a value in an object, used to hide all the logic that goes into
///     handling this sort of thing, so that is works elegantly in a single line.
/// </summary>
/// <param name="target"></param>
/// <param name="propertyName"></param>
/// <param name="propertyValue"></param>
public static void SetPropertyValueFromString(this object target,               
                              string propertyName, string propertyValue)
{
    PropertyInfo oProp = target.GetType().GetProperty(propertyName);
    Type tProp = oProp.PropertyType;

    //Nullable properties have to be treated differently, since we 
    //  use their underlying property to set the value in the object
    if (tProp.IsGenericType
        && tProp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
    {
        //if it's null, just set the value from the reserved word null, and return
        if (propertyValue == null)
        {
            oProp.SetValue(target, null, null);
            return;
        }

        //Get the underlying type property instead of the nullable generic
        tProp = new NullableConverter(oProp.PropertyType).UnderlyingType;
    }

    //use the converter to get the correct value
    oProp.SetValue(target, Convert.ChangeType(propertyValue, tProp), null);
}
2 голосов
/ 01 октября 2011

Универсальный конвертер типов - это то, что вы ищете!? Нелегкий подвиг ..

Попробуйте этот подход:

Универсальный преобразователь типа

Вы можете в NuGet Install-Package UniversalTypeConverter

Кроме того, здесь можно использовать Generics? Это облегчило бы решение, если бы вы знали хотя бы целевой тип конверсии.

1 голос
/ 01 октября 2011

Вот еще один способ сделать это, но я не уверен,

Без поддержки универсальных типов:

public void Foo(object obj,string propertyName,object value) 
{ 
    //Getting type of the property og object. 
    Type type = obj.GetType().GetProperty(propertyName).PropertyType;

    obj.GetType().GetProperty(propertyName).SetValue(obj, Activator.CreateInstance(type, value), null);
} 

С поддержкой универсальных типов:

public void Foo(object obj,string propertyName,object value) 
{ 
    //Getting type of the property og object. 
    Type type = obj.GetType().GetProperty(propertyName).PropertyType;

    if (type.IsGenericType)
        type = type.GetGenericArguments()[0];

    obj.GetType().GetProperty(propertyName).SetValue(obj, Activator.CreateInstance(type, value), null);
} 
0 голосов
/ 21 июля 2016

Я использовал функцию Convert в C #.То, как я делаю свое преобразование - это использование отражения.Вы даже можете переключаться и иметь несколько типов, которые вы хотите отразить тоже.

0 голосов
/ 01 октября 2011

Я не уверен, что это работает, но попробуйте:

public static T To<T>(this IConvertible obj)
{
  return (T)Convert.ChangeType(obj, typeof(T));
}

Public void Foo(object obj,string propertyName,object value)
{
    Type t= obj.GetType().GetProperty(propName).PropertyType;
    obj.GetType().GetProperty(propName).SetValue(obj, value.To<t>(), null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...