TypeDescriptor CanConvertFrom Bug?或者我做错了?

时间:2010-12-15 09:15:18

标签: c# system

这是从http://dnpextensions.codeplex.com/取得的扩展方法。

我理解字符串“test”不是数字字符串......

据我所知,GetConverter(targetType)的类型为int ...

我不明白为什么它说它可以从字符串转换......但它失败了......

/// <summary>
///     Converts an object to the specified target type or returns the default value.
/// </summary>
/// <typeparam name = "T"></typeparam>
/// <param name = "value">The value.</param>
/// <param name = "defaultValue">The default value.</param>
/// <returns>The target type</returns>
public static T ConvertTo<T>(this object value, T defaultValue)
{
    if (value != null)
    {
        var targetType = typeof(T);
        var valueType = value.GetType();

        if (valueType == targetType) return (T)value;

        var converter = TypeDescriptor.GetConverter(value);
        if (converter != null)
        {
            if (converter.CanConvertTo(targetType))
                return (T)converter.ConvertTo(value, targetType);
        }

        converter = TypeDescriptor.GetConverter(targetType);
        if (converter != null)
        {
            if (converter.CanConvertFrom(valueType))
                return (T)converter.ConvertFrom(value);
        }
    }
    return defaultValue;
}

    [TestMethod]
    public void TestConvertToWillFail()
    {
        // Arrange
        var value = "test";

        // Act
        var result = value.ConvertTo<int>();

        // Assert
        result.Should().Equal(0);
        result.Should().Not.Equal(value);
    }

    [TestMethod]
    public void TestConvertToShouldPass()
    {
        // Arrange
        var value = 123;
        var stringValue = "123";

        // Act
        var stringResult = stringValue.ConvertTo<int>();

        // Assert
        stringResult.Should().Equal(value);
        stringResult.Should().Not.Equal(0);
    }

注意:()来自Should.codeplex.com


测试中的例外:

  

test不是Int32的有效值。

3 个答案:

答案 0 :(得分:6)

您的方法在第二次调用中所做的是:

  • 获取StringConverter
  • 询问它是否可以转换为整数 - 它回答
  • 获取IntegerConverter
  • 询问它是否可以从字符串转换 - 它回答
  • 要求它转换提供的值(“test”) - 这就是它爆炸的地方,因为“test”确实不是Int32的有效值。

CanConvertFrom/To方法只是验证调用是否有意义,而不是转换是否成功,因为CanConvert仅适用于类型级

有些字符串会转换为有效整数,但这并不意味着所有字符串都是有效整数,因此即使ConvertFrom/To返回true,CanConvert也会抛出异常。

答案 1 :(得分:1)

这是我的工作。 如果有更好的版本,请告诉我。

/// <summary>
///     Converts an object to the specified target type or returns the default value.
/// </summary>
/// <typeparam name = "T"></typeparam>
/// <param name = "value">The value.</param>
/// <param name = "defaultValue">The default value.</param>
/// <returns>The target type</returns>
public static T ConvertTo<T>(this object value, T defaultValue)
{
    if (value != null)
    {
        try
        {
            var targetType = typeof(T);
            var valueType = value.GetType();

            if (valueType == targetType)
                return (T)value;

            var converter = TypeDescriptor.GetConverter(value);
            if (converter != null)
            {
                if (converter.CanConvertTo(targetType))
                    return (T)converter.ConvertTo(value, targetType);
            }

            converter = TypeDescriptor.GetConverter(targetType);
            if (converter != null)
            {
                if (converter.CanConvertFrom(valueType))
                {

                    return (T)converter.ConvertFrom(value);

                }
            }
        }
        catch (Exception e)
        {
            return defaultValue;
        }
    }
    return defaultValue;
}

答案 2 :(得分:0)

ConvertTo can throw exceptions如果它无法执行转换......即使CanConvertTo返回true。

e.g。 “12”可以转换为整数,但“test”不能。然而,转换器会说可以将从字符串转换为整数。