TypeDescriptor CanConvertFrom Bug?或者我做错了?

发布于 2024-10-07 16:09:48 字数 2106 浏览 0 评论 0原文

这是从 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() 来自 Should.codeplex.com


测试异常:

test 不是 Int32 的有效值。

This is an extension method taken out from http://dnpextensions.codeplex.com/.

I understand that the string "test" isn't a number string...

I understand that the GetConverter(targetType) is of type int...

What I don't understand is why it say it can convert from a string... but it fail...

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

Note: Should() is from Should.codeplex.com


Exception from test:

test is not a valid value for Int32.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深居我梦 2024-10-14 16:09:49

您的方法在第二次调用中执行的操作是:

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

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

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

What your method is doing in the second call is:

  • Get the StringConverter
  • Ask it if it can convert to integers - it answers no
  • Get the IntegerConverter
  • Ask it if it can convert from string - it answers yes
  • Ask it to convert the provided value ("test") - and this is where it blows up, since "test" is indeed not a valid value for Int32.

The CanConvertFrom/To methods are just to verify if the call makes sense at all, not whether the conversion will succeed, since CanConvert works only on the type level

There are strings that will convert to valid integers, but that does not mean that all strings are valid integers, so ConvertFrom/To will throw exceptions, even if the CanConvert return true.

微凉 2024-10-14 16:09:49

这是我的工作。
请让我知道是否有更好的版本。

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

This is my work around.
Please let me know if there's a better version of this out there.

/// <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;
}
若水微香 2024-10-14 16:09:49

如果无法执行转换,ConvertTo 可能会引发异常。即使 CanConvertTo 返回 true。

例如,“12”可以转换为整数,但“test”不能。但是转换器会说它可以从字符串转换为整数。

ConvertTo can throw exceptions if it is not able to perform the conversion... even if CanConvertTo returns true.

e.g. "12" can be converted to an integer but "test" cannot be. However the converter would say that it can convert from string to integer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文