【问题标题】:How to Convert a String to a Nullable Type Which is Determined at Runtime?如何将字符串转换为在运行时确定的可空类型?
【发布时间】:2012-03-14 18:15:06
【问题描述】:

我有以下代码,我需要将字符串转换为也从 String 指定的类型:

 Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");

            object d = Convert.ChangeType("2012-02-23 10:00:00", t);

我收到以下错误消息:

Invalid cast from 'System.String' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

这怎么可能?

我知道一种丑陋的方法是使用 if 检查类型是否可以为空:

    Type possiblyNullableType = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");

    var underlyingType = Nullable.GetUnderlyingType(possiblyNullableType);

    Object result;

    // if it's null, it means it wasn't nullable
    if (underlyingType != null)
    {
        result = Convert.ChangeType("2012-02-23 10:00:00", underlyingType);
    }

有没有更好的办法?

谢谢,

【问题讨论】:

    标签: c# asp.net generics datetime nullable


    【解决方案1】:
    public static T GetValue<T>(string Literal, T DefaultValue)
        {
            if (Literal == null || Literal == "" || Literal == string.Empty) return DefaultValue;
            IConvertible obj = Literal;
            Type t = typeof(T);
            Type u = Nullable.GetUnderlyingType(t);
    
            if (u != null)
            {
                return (obj == null) ? DefaultValue : (T)Convert.ChangeType(obj, u);
            }
            else
            {
                return (T)Convert.ChangeType(obj, t);
            }
        }
    

    【讨论】:

      【解决方案2】:

      我编写了以下通用辅助方法,该方法适用于大多数场景(未使用通用类型进行测试):

      static void Main(string[] args)
      {
          Object result =
              ConvertValue(
                  "System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]",
                  "2012-02-23 10:00:00");
      }
      
      public static Object ConvertValue(string typeInString, string value)
      {
          Type originalType = Type.GetType(typeInString);
      
          var underlyingType = Nullable.GetUnderlyingType(originalType);
      
          // if underlyingType has null value, it means the original type wasn't nullable
          object instance = Convert.ChangeType(value, underlyingType ?? originalType);
      
          return instance;
      }
      

      【讨论】:

      • 谢谢。这是最优雅、最有效的解决方案。
      【解决方案3】:

      这样的?除非你真的需要动态地做。

      if (string.IsNullOrEmpty(input))
      {
         return new DateTime?();
      }
      else
      {
         return new DateTime?(DateTime.Parse(input));
      }
      

      您可能可以检查您的类型是否是“可空”类型之一,然后也许您可以在这里找到有用的东西:

      Convert string to nullable type (int, double, etc...)

      【讨论】:

      • 我不能指定DateTime,它是在运行时确定的。
      • return new DateTime?(); 应替换为 return null;
      • 或许您可以提供更多关于您正在尝试做的事情的信息,而不是我们现在正在做的事情?
      【解决方案4】:

      有两个问题。

      首先,Convert.ChangeType just plain 不支持可空类型。

      其次,即使是这样,通过将结果装箱(将其分配给object),您已经将其转换为DateTime

      您可以特殊情况下可为空的类型:

      string s = "2012-02-23 10:00:00";
      Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");
      object d;
      
      if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
      {
          if (String.IsNullOrEmpty(s))
              d = null;
          else
              d = Convert.ChangeType(s, t.GetGenericArguments()[0]);
      }
      else
      {
          d = Convert.ChangeType(s, t);
      }
      

      【讨论】:

      • 为什么需要检查 t.IsGenericType? t.GetGenericTypeDefinition() == typeof(Nullable) 部分将涵盖这一点;不会吗?
      • 如果类型不是泛型,@William GetGenericTypeDefinition() 会抛出异常。
      • 非常感谢这个优雅的解决方案,你拯救了我的一天!
      猜你喜欢
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 2012-09-19
      • 1970-01-01
      • 2022-08-18
      • 2013-11-27
      • 2021-03-18
      相关资源
      最近更新 更多