Преобразование общего типа FROM string
У меня есть класс, который я хочу использовать для хранения "свойств" для другого класса. Эти свойства просто имеют имя и значение. В идеале, я хотел бы иметь возможность добавлять типизированные свойства, так что возвращаемое значение "value" всегда относится к типу, который я хочу, чтобы он был.
Тип всегда должен быть примитивным. Этот класс подклассифицирует абстрактный класс, который в основном сохраняет имя и значение как строку. Идея заключается в том, что этот подкласс добавит некоторую безопасность типа к базовому классу (а также сохранит меня при некотором преобразовании).
Итак, я создал класс, который (примерно) это:
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
Итак, вопрос:
Есть ли "общий" способ преобразования из строки обратно в примитив?
Я не могу найти какой-либо общий интерфейс, который связывает преобразование по всем направлениям (что-то вроде ITryParsable было бы идеальным!).
Ответы
Ответ 1
Я не уверен, правильно ли понял ваши намерения, но посмотрим, поможет ли это.
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
set { base.Value = value.ToString();}
}
}
Ответ 2
Метод lubos hasko завершается с ошибкой для nullables. Ниже приведенный метод будет работать с ошибками. Я не придумал это. Я нашел его через Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Кредит "Тунец Токсоз"
Использование сначала:
TConverter.ChangeType<T>(StringValue);
Класс ниже.
public static class TConverter
{
public static T ChangeType<T>(object value)
{
return (T)ChangeType(typeof(T), value);
}
public static object ChangeType(Type t, object value)
{
TypeConverter tc = TypeDescriptor.GetConverter(t);
return tc.ConvertFrom(value);
}
public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
{
TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
}
}
Ответ 3
Для многих типов (integer, double, DateTime и т.д.) существует статический метод Parse. Вы можете вызвать его с помощью отражения:
MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );
if (m != null)
{
return m.Invoke(null, new object[] { base.Value });
}
Ответ 4
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)
TypeDescriptor
- это класс, имеющий метод GetConvertor
, который принимает объект Type
, а затем вы можете вызвать метод ConvertFrom
для преобразования value
для указанного объекта.
Ответ 5
Вы можете использовать конструкцию, такую как класс признаков. Таким образом, у вас будет параметризованный вспомогательный класс, который знает, как преобразовать строку в значение своего собственного типа. Тогда ваш получатель может выглядеть так:
get { return StringConverter<DataType>.FromString(base.Value); }
Теперь я должен указать, что мой опыт с параметризованными типами ограничен С++ и его шаблонами, но я полагаю, что есть способ сделать то же самое, используя С# generics.
Ответ 6
Проверьте статический Nullable.GetUnderlyingType
.
- Если базовый тип имеет значение null, то параметр шаблона не Nullable
, и мы можем использовать этот тип напрямую
- Если базовый тип не является нулевым, используйте базовый тип в преобразовании.
Кажется, работает для меня:
public object Get( string _toparse, Type _t )
{
// Test for Nullable<T> and return the base type instead:
Type undertype = Nullable.GetUnderlyingType(_t);
Type basetype = undertype == null ? _t : undertype;
return Convert.ChangeType(_toparse, basetype);
}
public T Get<T>(string _key)
{
return (T)Get(_key, typeof(T));
}
public void test()
{
int x = Get<int>("14");
int? nx = Get<Nullable<int>>("14");
}
Ответ 7
public class TypedProperty<T> : Property
{
public T TypedValue
{
get { return (T)(object)base.Value; }
set { base.Value = value.ToString();}
}
}
Я использую преобразование через объект. Это немного проще.
Ответ 8
Я использовал лобос, и он работает. Но у меня возникла проблема с преобразованием удвоений из-за настроек культуры. Поэтому я добавил
return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);
Ответ 9
Еще одна вариация. Ручки Nullables, а также ситуации, когда строка является нулевой, а T не может быть недействительной.
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get
{
if (base.Value == null) return default(T);
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
return (T)Convert.ChangeType(base.Value, type);
}
set { base.Value = value.ToString(); }
}
}