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

C# 有没有办法禁用从UInt32到char的隐式强制转换?,c#,implicit-conversion,C#,Implicit Conversion,我正在编写一段代码,该代码以特定协议定义的大量ascii文本作为输入。原始作者将原始协议中的“字符串(1)”数据类型解释为代码中的字符 在您有代码的情况下,会出现很多微妙的错误,例如: char theChar = whatever(); if(theChar == 7) {...} 真正的意思是: if(theChar == '7') {...} 为了尝试一次捕获所有这些,有没有办法禁用对“char”的隐式转换?如果没有,那么跟踪所有这些问题的最佳方法是什么?作为“一次修复”解决方案,我

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

在您有代码的情况下,会出现很多微妙的错误,例如:

char theChar = whatever();
if(theChar == 7) {...} 
真正的意思是:

if(theChar == '7') {...}
为了尝试一次捕获所有这些,有没有办法禁用对“char”的隐式转换?如果没有,那么跟踪所有这些问题的最佳方法是什么?

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


为了避免在将来的重构中出现问题,最好使用自定义数据类型而不是char,这样您就可以定义所需的确切操作。

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


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

< P>不,允许表达式“代码> THAR==7 < /CODE >的行为是C规范的一部分,不能更改。 注意,这里实际的隐式转换是从char到int,而不是从int到char

下面是它的工作原理:

  • 文本
    7
    具有类型
    int
  • 变量
    theChar
    的类型为
    char
  • 要将
    =
    运算符应用于这两个表达式,编译器必须选择
    =
    运算符。
    • 没有一个
      =
      运算符将
      char
      作为第一个参数,将
      int
      作为第二个参数
    • 没有从
      int
      char
      的隐式转换(因为这样的转换可能会丢失信息)
    • 存在从
      char
      int
      的隐式转换
    • 编译器将
      char
      表达式转换为
      int
      ,并使用接受两个
      int
      =
      运算符

我建议使用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;
产生了编译错误


不幸的是,这无助于解决您眼前的问题:许多现有代码都包含这类错误。

Ugh,我不想禁用任何内置类型行为,这只是自找麻烦。至于查找它们,您可以创建一个自定义FxCop(代码分析)规则…+1适用于棘手的问题,而不是理想的解决方案。请注意,这个问题的解决方案是严格的提交前代码检查。@AnthonyPegram我确实同意这些隐式转换值得禁用,一直都很烦人。例如,ATM我正在重构一个代码以使用终端-我正在慢慢地陷入对di的困惑之中目录字符串和文件名字符串。因此,我创建了两个类,将负担转移到编译器,开始更改参数类型……您认为编译器是否抛出了一个错误(除了构造函数不匹配之外)?不!对于每一个使用字符串的操作,它都会悄悄地将类转换为字符串。以防万一,我会玩昆虫文明游戏-现在我知道了一种增加虫子数量的很棒的方法。@嗨,在这个特定的转换中,听起来让转换“显式”(如C#关键字)可能是一个解决方案?