有没有一种方法可以禁用从UInt32到char的隐式强制转换



我正在编写一段代码,该代码将大量由特定协议定义的ascii文本作为输入。原始作者将原始协议中的"字符串(1)"数据类型解释为代码中的字符。

在你有代码的情况下,有很多微妙的错误,比如:

char theChar = whatever();
if(theChar == 7) {...} 

真正的意义是:

if(theChar == '7') {...}

为了尝试一次捕获所有这些,有没有办法禁用隐式转换为"char"?如果没有,追踪所有这些的最佳方法是什么?

您应该能够为不允许从int进行隐式强制转换的char(将char作为其数据,并提供一些强制转换运算符以允许将其用作char)编写一个普通的替换类,然后搜索"char"并将其替换为"mychar"。这将引发编译器错误,您可以修复这些错误,然后如果您希望,可以再次将代码恢复为使用char,或者继续使用您的类。

这是一个很好的例子,说明在c++中临时使用宏非常有用。。。

我建议使用Visual Studio使用正则表达式在整个解决方案(Ctrl+Shift+F)中执行搜索,以查找现有的错误(如所描述的错误)。

  • 按Ctrl+Shift+F
  • 在"查找选项"下选择"使用:正则表达式"
  • 在"查找内容"字段中输入以下正则表达式:[^0-9a-zA-Z_][0-9]+[^0-9]

我认为这将列出源代码中出现的所有文字数字。然后,您可以浏览搜索结果,看看是否有任何搜索结果需要进一步调查。

您可以通过关注特定类型的问题来进一步缩小搜索结果的范围。例如,要在提供的示例中查找代码,可以将表达式调整为:==(|\t|r\n)*[0-9]+[^0-9]


原始答案

除了尽量避免代码中的"神奇"值之外,我无法提供任何好的建议来避免这个问题。

假设这个代码被用于某种菜单选择逻辑,我觉得这个代码应该是这样的:

static class MenuSelection
{
    public const char Open = '1';
    public const char Edit = '2';
    public const char Save = '3';
    // ...
    public const char Close = '7';
}

然后在if语句中使用MenuSelection,如下所示:

char theChar = whatever();
if(theChar == MenuSelection.Close) {...} 

这并不能真正解决从UInt32到char的隐式转换问题,但希望为MenuSelection类中的常量编写代码的人不会忘记引号。

编辑:哦,尝试一下之后,这似乎确实解决了隐式转换问题,因为public const char Close = 7;会产生编译错误。

不幸的是,这并不能帮助你解决眼前的问题:许多现有的代码都包含这类错误。

作为"一次性修复"解决方案,我认为James Michael Hare的FxCop解决方案是最简单的。

为了避免它在未来的重构中成为一个问题,使用自定义数据类型而不是char,这样你就可以定义你想要的确切操作,这可能是一个好主意。

否,允许表达式theChar == 7的行为是C#规范的一部分,不能更改。

请注意,这里实际的隐式转换是从char到int,而不是从int到char。

以下是它的工作原理:

  • 文字7的类型为int
  • 变量theChar的类型为char
  • 若要将==运算符应用于这两个表达式,编译器必须选择一个==运算符。
    • 不存在将char作为第一个自变量、将int作为第二个自变量的==运算符
    • 不存在从intchar的隐式转换(因为这样的转换可能丢失信息)
    • 其中是从charint的隐式转换
    • 编译器将char表达式转换为int,并使用取两个ints==运算符

最新更新