【问题标题】:Weird warning converting VB.NET to C# - Hexadecimal Constants将 VB.NET 转换为 C# 的奇怪警告 - 十六进制常量
【发布时间】:2012-07-10 10:29:29
【问题描述】:

除非我使用 HTML,否则我通常不会处理十六进制数字,因此我在转换涉及它们的代码方面确实没有太多经验。本质上,这里的问题是我正在将一些类从 VB.NET 转换为 C#.NET,并且有几个地方 VB 版本将一些值与十六进制常量进行比较。当我将该值转换为其 C# 等效项时,我从 Visual Studio 收到以下“警告”消息:

比较积分常数没用,常数在外面 'int'类型的范围

现在,显然 VB 版本没有这个警告,否则我不会费心问这个问题。我会注意到,如果我将要比较的属性转换为 Int64,警告就会消失。

我想知道我是否做对了,我是否不应该放弃整个比较,因为它显然不适用于现实世界的场景?

VB 代码:

    Catch ex As COMException
        If bInsert AndAlso ex.ErrorCode = &H80042776 Then
            ' DO THINGS
    End Try

C#代码:

        catch (COMException come)
        {
            if (insert && come.ErrorCode == 0x80042776)
            {
                // DO THINGS
            }
        }

【问题讨论】:

标签: c# vb.net warnings vb.net-to-c#


【解决方案1】:

我不知道这在 VB.NET 中是否有效(不确定那里的规则),但 C# 不会轻易让您指定这样的负数。我想你不得不说

...    come.ErrorCode == unchecked((int)0x80042776)

否则,恐怕 C# 不会将其视为 32 位负整数。即使您的代码已经在 unchecked 上下文中编译(我敢打赌!),您仍然必须像上面那样显式编写 unchecked,当它是一个编译时常量时,您正在“转换”。

当 8 个十六进制数字非常适合 32 位 (System.Int32) 时,这很烦人。

【讨论】:

  • 是否相当于将COMException.ErrorCode 转换为uint
  • @Matt 是的,但仅限于unchecked 上下文。我的方式是最安全的。我刚刚对您找到的其他问题的答案添加了评论。
【解决方案2】:

在 VB.NET 中,当涉及到integer literals

整数范围之外的值被键入为 Long

【讨论】:

  • COMException 对象的 ErrorCode 不还是受限于 Int32 约束吗? (或者 VB 中“Integer”类型的默认实现是什么)或者如果值不合适,VB 中的 Integer 类型是否也会变为“Long/Int64”?
【解决方案3】:

COMException::ErrorCode 是 int32 类型。所以它的最大值是 2^31 - 1. (2,147,483,647)。

您正在与一个十六进制数 0x80042776 进行比较。十进制值为 2,147,755,894。

这些数字非常接近,但请注意十六进制数字大于 int32 可能的最大数字。这就是编译器警告您的内容。在 VB 中也是如此,只是编译器没有警告你。

魔法十六进制常数从何而来?这可能是错误的。

【讨论】:

  • 该常量来自 Kofax Capture 导出连接器的一些源代码。没有解释它应该是什么意思,所以我真的不知道它为什么在那里。
  • 在许多领域,如果前导数字是 8F,则始终将十六进制数解释为负数,然后他的常数是 inside我们签名的Int32 的范围。问题是 C# 在这里没有使用该约定。看我的回答。
  • 在 vb.net 中,在 &h80000000 到 &hFFFFFFFF 范围内的十六进制常量在没有尾随类型说明符 uilul 或 @987654327 的情况下被解释为有符号整数@。尽管我很喜欢 vb.net,但我发现这种行为很烦人,尤其是因为 即使数字以前导零书写时它也适用!实际上,我希望看到语言执行句柄计算“好像”操作数是Int64,但要认识到在什么情况下可以跳过上部。 longVar = longVar And Not 0x40000000longVar = longVar And Not 0x100000000 一样有效,但...
  • ...longVar = longVar and 0x80000000 失败;这些语句的 C# 等效项表现出类似的行为。恶心。
【解决方案4】:

好的,所以我对该问题进行了一些额外的搜索(可能应该先这样做),并找到了我正在寻找的答案。事实证明,COMException 的 ErrorCode 实际上是一个 UNSIGNED 整数(参见 HRESULT)。也许 VB 也会自动处理这个问题?

我在这里看到了详细的堆栈溢出帖子:Catching COMException specific Error Code - 查看问题的选择答案

在我标记答案之前,我想听听其他人对此的回复。

【讨论】:

  • 对于 .NET,ErrorCode已签名 Int32,但它可以(当然)转换为未签名的。见the MSDN documentationCOMException 类从 ExternalException 继承其 ErrorCode
猜你喜欢
  • 2018-04-14
  • 2017-07-31
  • 2013-07-20
  • 2012-06-17
  • 2023-04-06
  • 2011-08-04
  • 2016-01-17
  • 1970-01-01
  • 2021-06-26
相关资源
最近更新 更多