C# 字符串的泛型类型转换

C# 字符串的泛型类型转换,c#,generics,primitive,type-safety,C#,Generics,Primitive,Type Safety,我有一个类,我想用它来存储另一个类的“属性”。这些属性只有一个名称和一个值。理想情况下,我希望能够添加类型化属性,以便返回的“值”始终是我希望的类型 类型应始终为基元。这个类是一个抽象类的子类,它基本上将名称和值存储为字符串。这个想法是,这个子类将向基类添加一些类型安全性(以及节省一些转换) 因此,我创建了一个类,大致如下: 公共类类型属性:属性 { 公共数据类型TypedValue { 获取{//这里有问题!} set{base.Value=Value.ToString();} } } 因此

我有一个类,我想用它来存储另一个类的“属性”。这些属性只有一个名称和一个值。理想情况下,我希望能够添加类型化属性,以便返回的“值”始终是我希望的类型

类型应始终为基元。这个类是一个抽象类的子类,它基本上将名称和值存储为字符串。这个想法是,这个子类将向基类添加一些类型安全性(以及节省一些转换)

因此,我创建了一个类,大致如下:

公共类类型属性:属性
{
公共数据类型TypedValue
{
获取{//这里有问题!}
set{base.Value=Value.ToString();}
}
}
因此,问题是:

是否有“通用”方法将字符串转换回原语?


我似乎找不到任何通用接口来链接所有的转换(像ITryParsable这样的东西是理想的!)。

您可能会使用一个构造,例如。通过这种方式,您将拥有一个参数化的helper类,它知道如何将字符串转换为自己类型的值。那么您的getter可能如下所示:

get { return StringConverter<DataType>.FromString(base.Value); }
get{return StringConverter.FromString(base.Value);}

现在,我必须指出,我对参数化类型的经验仅限于C++及其模板,但我想用C语言泛型也有一些方法可以做到这一点。

< P>我不确定我是否正确理解了你的意图,但让我们看看这是否有帮助。
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();}
    }
}
公共类TypedProperty:属性,其中T:IConvertible
{
公共T型价值
{
获取{return(T)Convert.ChangeType(base.Value,typeof(T));}
set{base.Value=Value.ToString();}
}
}
对于许多类型(integer、double、DateTime等),都有一个静态解析方法。您可以使用反射调用它:

MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );

if (m != null)
{
    return m.Invoke(null, new object[] { base.Value });
}

lubos hasko的方法对于空值失败。下面的方法适用于nullables。不过我没想到。我通过谷歌找到的:归功于“金枪鱼托克索兹”

首先使用:

TConverter.ChangeType<T>(StringValue);  
TConverter.ChangeType(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)));
    }
}
公共静态类TConverter
{
公共静态T ChangeType(对象值)
{
返回(T)更改类型(类型(T),值);
}
公共静态对象ChangeType(类型t,对象值)
{
TypeConverter tc=TypeDescriptor.GetConverter(t);
返回tc.ConvertFrom(值);
}
公共静态无效注册表TypeConverter(),其中TC:TypeConverter
{
AddAttributes(typeof(T),新的TypeConverterAttribute(typeof(TC));
}
}
公共类类型属性:属性
{
公共T型价值
{
获取{return(T)(object)base.Value;}
set{base.Value=Value.ToString();}
}
}
我使用通过对象进行转换。这有点简单

TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)

TypeDescriptor
是一个类,它有一个方法
GetConvertor
,它接受一个
Type
对象,然后你可以调用
ConvertFrom
方法来转换指定对象的
值。但是由于文化背景的原因,我在转换双打时遇到了一个问题。所以我补充说

return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);

检查静态
可为空。GetUnderlyingType
。 -如果基础类型为null,则模板参数不可为null,我们可以直接使用该类型 -如果基础类型不为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 object Get(string\u toparse,Type\t)
{
//测试是否为Nullable并返回基类型:
类型undertype=Nullable.getunderyingType(\u t);
类型basetype=undertype==null?\t:undertype;
返回Convert.ChangeType(\u toparse,basetype);
}
公共T获取(字符串_键)
{
返回(T)Get(_键,typeof(T));
}
公开无效测试()
{
int x=获取(“14”);
int?nx=获取(“14”);
}

还有另一种变化。处理可为null的内容,以及字符串为null且T不可为null的情况

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(); }
    }
}
公共类TypedProperty:属性,其中T:IConvertible
{
公共T型价值
{
得到
{
if(base.Value==null)返回默认值(T);
变量类型=可空。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));
        }
}
公共静态类转换扩展
{
公共静态对象转换(此对象值,类型t)
{
类型underlyingType=Nullable.GetUnderlyingType(t);
if(underlyngtype!=null&&value==null)
{
返回null;
}
类型basetype=underlyngType==null?t:underlyngType;
返回系统.Convert.ChangeType(值,basetype);
}
公共静态T转换(此对象值)
{
返回(T)值。转换(typeof(T));
}
}
例子

            string stringValue = null;
            int? intResult = stringValue.Convert<int?>();

            int? intValue = null;
            var strResult = intValue.Convert<string>();
string stringValue=null;
智力?intResult=stringValue.Convert();
智力?intValue=null;
var strResult=intValue.Convert();

您可以在一行中完成,如下所示:

YourClass obj = (YourClass)Convert.ChangeType(YourValue, typeof(YourClass));

快乐编码;)

几天来我一直在想如何将流反序列化为泛型类型。谢谢:)我同意,虽然
Convert.ChangeType
不是非常通用和可扩展的解决方案,但它适用于大多数基本类型。如果需要更好的方法,可以像Tim建议的那样将此方法包装成更大的方法,或者使用不同的转换方法alto
            string stringValue = null;
            int? intResult = stringValue.Convert<int?>();

            int? intValue = null;
            var strResult = intValue.Convert<string>();
YourClass obj = (YourClass)Convert.ChangeType(YourValue, typeof(YourClass));