泛型类型转换 FROM 字符串

Posted

技术标签:

【中文标题】泛型类型转换 FROM 字符串【英文标题】:Generic type conversion FROM string 【发布时间】:2010-09-05 17:39:55 【问题描述】:

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

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

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

public class TypedProperty<DataType> : Property

    public DataType TypedValue
    
        get  // Having problems here! 
        set  base.Value = value.ToString();
    

所以问题是:

有没有一种“通用”的方法可以将字符串转换回原语?

我似乎找不到任何通用接口来链接整个转换(像 ITryParsable 这样的接口会很理想!)。

【问题讨论】:

我很想看看你的具体类的例子,即使只是一个 sn-p。 :) 你能把你的基类的相关部分贴出来吗? 我想知道是否有人可以在 .Net Standard 1.2 中获得答案:/ 【参考方案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();
    

【讨论】:

我这几天一直想知道如何将流反序列化为泛型类型。谢谢:) 我同意,虽然Convert.ChangeType 不是非常通用和可扩展的解决方案,但它适用于大多数基本类型。如果需要更好的东西,可以像 Tim 建议的那样将这个方法包装成更大的东西,或者完全使用不同的转换方法。 我肯定会添加 where T:IConvertible Type T 不应该是 IConvertible,但 Type of base.Value 应该。【参考方案2】:

lubos hasko 的方法对 nullables 失败。下面的方法适用于可空值。不过,我没有想出来。我通过谷歌找到它:http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Credit to "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)));
    

【讨论】:

我会为枚举和其他复杂结构添加一个后备转换选项,但很好。 为什么是RegisterTypeConverter?我们需要事先注册转换器吗? (不幸的是链接已经死了,所以我无法阅读它) 对于多次转化,您应该只创建一次tcTypeConverter)。 TypeConverter 很慢,因为它使用反射来搜索 TypeConverterAttribute。如果您初始化单个私有TypeConverter 字段,那么您应该能够多次重复使用TypeConverter 工作正常,但如果 T 是 object,则会引发异常。我能够通过使用 ` if (typeof(T).IsPrimitive) return TConverter.ChangeType(StringValue); else object o=(object)StringValue;还给; ` 替代用法示例 TConverter.ChangeType&lt;T&gt;(StringValue)【参考方案3】:

对于许多类型(整数、双精度、日期时间等),有一个静态 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

【讨论】:

我个人认为这个接口比Convert.ChangeType方法更适合处理转换,因为你需要在你的所有类上实现IConvertible接口。【参考方案5】:

从Bob 的回答中获得灵感,这些扩展还支持空值转换和所有原语转换。

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

【讨论】:

【参考方案6】:

您可以使用traits class 之类的构造。这样,您将拥有一个参数化的帮助类,该类知道如何将字符串转换为其自己类型的值。那么你的吸气剂可能看起来像这样:

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

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

【讨论】:

C# 中不存在通用版本。【参考方案7】:

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

【讨论】:

【参考方案8】:
public class TypedProperty<T> : Property

    public T TypedValue
    
        get  return (T)(object)base.Value; 
        set  base.Value = value.ToString();
    

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

【讨论】:

谢谢我必须在界面中转换一个 T 并且简单的转换 T 对象可以正常工作,简单快捷,谢谢 (int)(object)"54";是致命的!,这不是 VB!【参考方案9】:

我使用了 lobos 答案,它有效。但是由于文化设置,我在转换 doubles 时遇到了问题。所以我加了

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

【讨论】:

【参考方案10】:

又一个变种。处理 Nullables,以及字符串为 null 且 T not 可为 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(); 
    

【讨论】:

【参考方案11】:

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

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

编码愉快 ;)

【讨论】:

当您分享代码作为答案时,请尝试解释一下。

以上是关于泛型类型转换 FROM 字符串的主要内容,如果未能解决你的问题,请参考以下文章

泛型集合和非泛型集合的区别

泛型,HashMap,爆类型转换错误

java中泛型的使用

Java之路 - SystemStringBuilder包装类字符串与基本数据类型的转换Collection泛型

泛型技巧系列:如何提供类型参数之间的转换

为啥 Java 泛型不允许对泛型类型进行类型转换?