我正在处理代码,该代码将特定协议定义的大量ascii文本作为输入。原作者将原始协议中的“string(1)”数据类型解释为代码中的字符。
在角落案例中存在许多微妙的错误,例如:
char theChar = whatever();
if(theChar == 7) {...}
真正的意思是:
if(theChar == '7') {...}
为了尝试一次捕获所有这些,有没有办法禁用隐式转换为'char'?如果没有,那么追踪所有这些的最佳方法是什么?
答案 0 :(得分:4)
你应该能够为char编写一个简单的替换类(它包含一个char作为其数据,并提供一些强制转换运算符以允许它被用作char它),它不允许隐式转换来自/来自ints,然后搜索并用'mychar'替换'char'。这会抛出你可以修复的编译器错误,然后如果你希望你可以将代码恢复为再次使用char,或坚持你的类。
这是一个很好的例子,临时使用宏在c ++中非常有用......
答案 1 :(得分:2)
我建议找到所描述的现有错误,使用Visual Studio使用正则表达式在整个解决方案(Ctrl + Shift + F)中执行搜索。
我认为这将列出源代码中所有出现的文字编号。然后,您可以浏览搜索结果,看看是否需要进一步调查。
您可以通过关注特定类型的问题来进一步缩小搜索结果范围。例如,要在提供的示例中查找代码,可以将表达式调整为以下内容:==(| \ 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
作为第二个参数。int
到char
的隐式转换(因为此类转换可能会丢失信息)。char
到int
的隐式转换。char
表达式转换为int
,并使用占用两个==
的{{1}}运算符。