【问题标题】:Why does the FormatException returned by a TypeConverter for an ushort-type refer to Int16?为什么 TypeConverter 为 ushort 类型返回的 FormatException 引用 Int16?
【发布时间】:2018-03-19 11:12:29
【问题描述】:

我正在用 C# 和 .NET Core 2.0.5 编写我的代码。当为 ushort 类型使用 TypeConverter 并且转换失败时,FormatException 消息指的是 Int16,而不是 UInt16。谁能给我解释一下?

我测试过的其他类型(decimal、double、float、int、long、short、uint、ulong)在错误消息中返回预期的类型名。

为了说明我的观点,这里有一个会失败的单元测试。错误消息显示“错误值不是 Int16 的有效值。”。

    [Fact]
    public void FailingToConvertUShort_GivesFormatExceptionMessage_WithCorrectType()
    {
        // Arrange
        var badvalue = "badvalue";
        var typeConverter = TypeDescriptor.GetConverter(typeof(ushort));

        try
        {
            // Act
            var result = typeConverter.ConvertFrom(context: null, culture: new CultureInfo("en-GB"), value: badvalue);
        }
        catch (Exception ex)
        {
            // Assert
            Assert.Equal($"badvalue is not a valid value for {typeof(ushort).Name}.", ex.Message);
        }
    }

这是测试的输出:

预期:···是 UInt16 的有效值。

实际:···t 是 Int16 的有效值。

【问题讨论】:

  • 首先 catch (Exception ex) 不仅在转换器错误时停止。它以 OutOfMemory、InvalidOperation、DevideByZero 和任何你无法想象的东西停止。如果您希望获得 FormatException,请放置 catch (FormatException)
  • 只是为了确认:您并不是真的在生产代码中依赖它,对吧?这只是证明问题的一种简单方法?一般来说,您不应该依赖任何异常的文本内容。 (即便如此,该消息在 .NET Framework 上具有预期的内容,因此这可能只是 Core 中的一个错误。)
  • 从问题来看,足以演示的代码示例应该是:Debug.WriteLine(typeof(ushort).Name);
  • 好吧,感谢上帝的开源。错误是fairly obvious:第18 行读取internal override Type TargetType => typeof(short);,而不是internal override Type TargetType => typeof(ushort);。可能是一些糟糕的复制粘贴。
  • 为了更好的衡量标准,here's the offending commit。最初是正确的(在 .NET Framework 上仍然如此)。

标签: c# .net-core typeconverter


【解决方案1】:

这是UInt16Converter 中的一个错误(您使用TypeDescriptor.GetConverter(typeof(ushort)) 返回的类型。具体来说,this line

internal override Type TargetType => typeof(short);

显然应该读为ushort 而不是short。这个错误是作为cleanup commit 的一部分引入的,用于使用表达式主体成员。

异常的消息似乎是唯一受影响的东西。在转换为字符串时,它还会在TypeConverter.ConvertTo 中选择稍微不同的代码路径,但这对UInt16 值的格式没有实际影响。请注意,此类的 tests 没有涵盖这一点:它们仅验证 ConvertFrom 是否抛出了无效值,而不是什么类型的异常或消息的内容。 (后者几乎可以肯定是设计使然,因为 .NET 异常消息是本地化的。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    相关资源
    最近更新 更多