【问题标题】:Is there any generic Parse() function that will convert a string to any type using parse?是否有任何通用 Parse() 函数可以使用解析将字符串转换为任何类型?
【发布时间】:2011-03-30 23:18:42
【问题描述】:

我想根据泛型返回类型将字符串转换为泛型类型,如intdatelong

基本上是一个类似Parse<T>(String) 的函数,它返回T 类型的项目。

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

【问题讨论】:

    标签: c# string parsing type-conversion


    【解决方案1】:

    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 ,所以我认为这个函数会进行某种类型的转换而不是解析
    • MSDN 说它只是一个在源对象上找到正确转换方法的包装器,要求它实现 IConvertible 接口。
    • 如果需要实现IConvertable不应该也约束T,即T ChangeType&lt;T&gt;(this object obj) where T : IConvertable吗?
    • @Liam:不,obj 必须是 IConvertible,但无法在编译时指定。
    • 如果我需要像 TryChangeType 这样在失败情况下返回 null 或 false 的东西?仅通过捕获异常?
    【解决方案2】:

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

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

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

    【讨论】:

    • 恕我直言,这是更好的答案,因为它还包含“可为空”方面
    • 您使用TypeDescriptor 可空类型和Convert.ChangeType 不可空类型是否有特定原因?整个try 块只能减少到TypeConverter 2 行代码,它适用于可空和不可空。
    【解决方案3】:

    Pranay's answer 的更简洁版本

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

    【讨论】:

      【解决方案4】:

      System.Convert.ChangeType 不会转换为任何类型。想一想:

      • 可为空的类型
      • 枚举
      • 指南等

      this implementation of ChangeType 可以实现这些转换。

      【讨论】:

        【解决方案5】:

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

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

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

        如果类型没有合适的解析方法,它也会回退到我上面提到的方法(参见自述文件中的performance section)。

        var v = new ValueString("15"); // struct
        var i = v.As<int>(); // Calls int.Parse.
        

        【讨论】:

          猜你喜欢
          • 2013-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多