FROM 字符串的通用类型转换
-
08-06-2019 - |
题
我有一个类,我想用它来存储另一个类的“属性”。这些属性只有一个名称和一个值。理想情况下,我希望能够添加 打字的 属性,以便返回的“值”始终是我想要的类型。
该类型应该始终是原始类型。该类是一个抽象类的子类,该类基本上将名称和值存储为字符串。这个想法是这个子类将为基类添加一些类型安全性(以及节省一些转换)。
所以,我创建了一个类(大致)是这样的:
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
所以问题是:
是否有一种“通用”方法可以从字符串转换回原语?
我似乎找不到任何通用接口来链接整个转换(比如 I尝试解析 本来就很理想!)。
解决方案
我不确定我是否正确理解了您的意图,但让我们看看这是否有帮助。
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();}
}
}
其他提示
lubos hasko 的方法对于可空值失败。下面的方法适用于可空值。不过,我没有想出这个办法。我通过谷歌找到了它: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx 归功于“Tuna Toksoz”
首先使用:
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)));
}
}
对于许多类型(整数、双精度、DateTime 等),都有一个静态 Parse 方法。您可以使用反射来调用它:
MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );
if (m != null)
{
return m.Invoke(null, new object[] { base.Value });
}
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)
TypeDescriptor
类是否有方法 GetConvertor
它接受一个 Type
对象,然后你可以调用 ConvertFrom
方法来转换 value
对于该指定对象。
您可以使用诸如 特质类. 。通过这种方式,您将拥有一个参数化帮助器类,它知道如何将字符串转换为其自己类型的值。那么你的吸气剂可能看起来像这样:
get { return StringConverter<DataType>.FromString(base.Value); }
现在,我必须指出,我对参数化类型的经验仅限于 C++ 及其模板,但我想有某种方法可以使用 C# 泛型来做同样的事情。
检查静电 Nullable.GetUnderlyingType
。- 如果基础类型为 null,则模板参数不是 Nullable
, ,并且我们可以直接使用该类型 - 如果基础类型不是null,则使用转换中的基础类型。
似乎对我有用:
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");
}
public class TypedProperty<T> : Property
{
public T TypedValue
{
get { return (T)(object)base.Value; }
set { base.Value = value.ToString();}
}
}
我使用通过对象进行转换。稍微简单一点。
我用了 lobos 答案,它有效。但我在转换时遇到了问题 双打 因为文化背景。所以我添加了
return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);
还有另一种变化。处理 Nullables,以及字符串为 null 且 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(); }
}
}
灵感来自于 鲍勃答案是,这些扩展还支持空值转换和所有原语转换。
public static class ConversionExtensions
{
public static object Convert(this object value, Type t)
{
Type underlyingType = Nullable.GetUnderlyingType(t);
if (underlyingType != null && value == null)
{
return null;
}
Type basetype = underlyingType == null ? t : underlyingType;
return System.Convert.ChangeType(value, basetype);
}
public static T Convert<T>(this object value)
{
return (T)value.Convert(typeof(T));
}
}
例子
string stringValue = null;
int? intResult = stringValue.Convert<int?>();
int? intValue = null;
var strResult = intValue.Convert<string>();