通用类型转换FROM字符串

时间:2008-08-12 09:13:24

标签: c# generics primitive type-safety

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

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

所以,我创建了一个(大致)这个类:

public class TypedProperty<DataType> : Property
{
    public DataType TypedValue
    {
        get { // Having problems here! }
        set { base.Value = value.ToString();}
    }
}

所以问题是:

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

我似乎无法找到任何通用的界面来链接整个转换(像 ITryParsable 这样的东西会是理想的!)。

10 个答案:

答案 0 :(得分:342)

我不确定我是否理解你的意图,但让我们看看这个是否有帮助。

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();}
    }
}

答案 1 :(得分:67)

lubos hasko的方法因为无效而失败。以下方法适用于无效。不过,我没想出来。我通过Google找到了它: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)));
    }
}

答案 2 :(得分:13)

对于许多类型(整数,双精度,日期时间等),有一个静态Parse方法。您可以使用反射来调用它:

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

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

答案 3 :(得分:6)

TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)

TypeDescriptor是具有方法GetConvertor的类,它接受Type对象,然后您可以调用ConvertFrom方法转换该指定对象的value

答案 4 :(得分:3)

您可以使用traits class之类的构造。通过这种方式,您将拥有一个参数化的辅助类,它知道如何将字符串转换为自己类型的值。那么你的getter可能是这样的:

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

现在,我必须指出,我对参数化类型的体验仅限于C ++及其模板,但我想有一些方法可以使用C#泛型做同样的事情。

答案 5 :(得分:2)

检查静态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");
}

答案 6 :(得分:0)

我使用了lobos答案并且它有效。但由于文化设置的原因,我对双打的转换存在问题。所以我添加了

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

答案 7 :(得分:0)

public class TypedProperty<T> : Property
{
    public T TypedValue
    {
        get { return (T)(object)base.Value; }
        set { base.Value = value.ToString();}
    }
}

我使用通过对象进行转换。这有点简单。

答案 8 :(得分:0)

另一种变化。处理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(); }
    }
}

答案 9 :(得分:-1)

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

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

快乐编码;)