从'System.String'到'System.TimeSpan'的转换无效。

15

我目前有一个通用方法,根据键从数据库中读取值并返回该值的特定类型。

    public T Get<T>(string key, T defaultValue)
    {
        var myparms = new List<SqlParameter>
                      {
                          new SqlParameter("@KEY", key),
                      };
        const string getPropertyQuery = "SELECT SPARM_VALUE FROM SYSPARAMS WHERE SPARM_KEY = @KEY;";

        var returnedValue = //Get value from Database

        if (returnedValue == null)
        {
            return defaultValue; //Value does not exists so return default.
        }

        return (T)Convert.ChangeType(returnedValue, typeof(T));
    }

但是当我尝试返回TimeSpan类型时,会出现以下异常:从'System.String'到'System.TimeSpan'的转换无效。 经过一番搜索,我发现最常见的解决方法是使用TimeSpan.ParseTimeSpan.TryParse方法。
我还找到了TimeSpan结构。
我的问题是为什么TimeSpan不能做到这一点。这是因为它没有IConvertible接口吗?对此有任何想法将不胜感激。
3个回答

37

我认为 Convert.ChangeType 并不是你真正想要的。尝试使用 TypeConverter.ConvertFrom

var converter = TypeDescriptor.GetConverter(typeof(T));
return converter.CanConvertFrom(returnedValue) ? 
    (T)converter.ConvertFrom(returnedValue) :
    defaultValue;

嗯,我以为Convert.ChangeType实际上使用了TypeConverters。啊,我看它只使用了IConvertable - leppie

1

stringTimeSpan 之间没有明确的强制转换定义,因为大多数字符串不是 TimeSpan

如果框架定义了这样的转换,您是否也希望在 DateTime 和所有其他值类型上存在这些转换?


有没有特定的原因,为什么没有 Convert.ToTimeSpan 方法?我知道并非所有值类型都有强制转换,但我觉得 Convert 类不包括 TimeSpan 很奇怪。 - Jethro
@Jethro - 可能是因为它没有被使用得像其他类那样频繁。而且 Convert 类已经有很多重载方法了,再添加更多只会增加这些方法的数量。 - Oded

1

StringTimeSpan 之间没有隐式转换,您需要使用 ParseTryParse 显式地进行转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接