是否有任何通用的Parse()函数可以使用parse将字符串转换为任何类型?


91

我想将字符串转换为通用类型,例如intdatelong基于通用返回类型。

基本上,像Parse<T>(String)这样的函数返回type的项目T

例如,如果传递了一个int函数应该在int.parse内部执行。

Answers:


132

System.Convert.ChangeType

根据您的示例,您可以执行以下操作:

int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));

为了满足您的“通用返回类型”要求,您可以编写自己的扩展方法:

public static T ChangeType<T>(this object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}

这将允许您执行以下操作:

int i = "123".ChangeType<int>();

很酷,但是奇怪的是它的名字叫ChangeType,所以我会认为这个函数执行某种类型的转换而不是解析
Karim 2010年

7
MSDN表示,它只是一个包装,可以在源对象上找到正确的转换方法,要求它实现IConvertible接口。
阿妮2010年

如果需要实施,IConvertable是否也应该限制T,即T ChangeType<T>(this object obj) where T : IConvertable
利亚姆

2
@Liam:不,obj必须是IConvertible,但是无法在编译时指定它。
阿尼(Ani)

如果我需要类似TryChangeType之类的方法,在失败的情况下返回null或false?仅通过捕获异常?
绝望的

21

好吧,看来我来不及回答这个问题了。但是这是我的实现:

基本上,我为Object类创建了一个Extension方法。它处理所有类型,即可为空,类和结构。

 public static T ConvertTo<T>(this object value)
           {
               T returnValue;

               if (value is T variable)
                   returnValue = variable;
               else
                   try
                   {
                       //Handling Nullable types i.e, int?, double?, bool? .. etc
                       if (Nullable.GetUnderlyingType(typeof(T)) != null)
                       {
                           TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                           returnValue = (T) conv.ConvertFrom(value);
                       }
                       else
                       {
                           returnValue = (T) Convert.ChangeType(value, typeof(T));
                       }
                   }
                   catch (Exception)
                   {
                       returnValue = default(T);
                   }

               return returnValue;
           }

恕我直言,这是更好的答案因为它也包含了“可空” -aspect
奥莱阿尔伯斯

为什么要TypeDescriptor为可空类型和Convert.ChangeType不可空类型使用特定的原因?整个try块只能缩减为TypeConverter两行代码,并且对可空和不可空都适用。
IMujagic


8

清洁Pranay答案的版本

public static T ConvertTo<T>(this object value)
{
    if (value is T variable) return variable;

    try
    {
        //Handling Nullable types i.e, int?, double?, bool? .. etc
        if (Nullable.GetUnderlyingType(typeof(T)) != null)
        {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
        }

        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (Exception)
    {
        return default(T);
    }
}

0

.NET中有两种约定可以将一种类型的对象转换为另一种类型。

但是这些方法比通常的要慢得多 T.Parse(string),导致装箱,并且每次您要转换单个值时都涉及大量分配。

对于ValueString,我选择使用反射找到合适的类型的静态解析方法,构建一个调用它的lambda表达式,并缓存已编译的委托以供将来使用(请参阅此答案以获取示例)。

如果类型没有合适的解析方法,它也会退回到我上面提到的方式(请参阅自述文件中的性能部分)。

var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.