有没有办法禁用从UInt32到char的隐式转换?

时间:2012-01-06 18:56:18

标签: c# implicit-cast

我正在处理代码,该代码将特定协议定义的大量ascii文本作为输入。原作者将原始协议中的“string(1)”数据类型解释为代码中的字符。

在角落案例中存在许多微妙的错误,例如:

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

真正的意思是:

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

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

4 个答案:

答案 0 :(得分:4)

你应该能够为char编写一个简单的替换类(它包含一个char作为其数据,并提供一些强制转换运算符以允许它被用作char它),它不允许隐式转换来自/来自ints,然后搜索并用'mychar'替换'char'。这会抛出你可以修复的编译器错误,然后如果你希望你可以将代码恢复为再次使用char,或坚持你的类。

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

答案 1 :(得分:2)

我建议找到所描述的现有错误,使用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;会产生编译错误。

不幸的是,它对您的直接问题没有帮助:许多现有代码包含这些类型的错误。

答案 2 :(得分:1)

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

为了防止将来重构使用自定义数据类型而不是char,这样你就可以定义你想要的确切操作可能是一个好主意。

答案 3 :(得分:0)

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

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

以下是它的工作原理:

  • 文字7的类型为int
  • 变量theChar的类型为char
  • 要将==运算符应用于这两个表达式,编译器必须选择==运算符。
    • 没有==运算符将char作为第一个参数,int作为第二个参数。
    • 没有从intchar的隐式转换(因为此类转换可能会丢失信息)。
    • 是从charint的隐式转换。
    • 编译器将char表达式转换为int,并使用占用两个==的{​​{1}}运算符。