预处理器错误和警告

编译器在预处理器指令使用不当时生成以下错误:

  • CS1024应有预处理器指令
  • CS1025预期单行注释或行尾
  • CS1027:应有 #endif 指令
  • CS1028意外的预处理器指令
  • CS1029#error:“text”
  • CS1030#warning:“text”
  • CS1032在文件中第一个令牌后无法定义/取消定义预处理器符号
  • CS1038预期的 #endregion 指令
  • CS1040预处理器指令必须显示为行上的第一个非空格字符
  • CS1517预处理器表达式无效
  • CS1560为预处理器指令指定的文件名无效。文件名太长或无效的文件名
  • CS1576为 #line 指令指定的行号缺失或无效
  • CS1578应提供文件名、单行注释或行尾
  • CS1633无法识别 #pragma 指令
  • CS1634预期禁用或还原
  • CS1635无法还原警告“警告代码”,因为它已全局禁用
  • CS1691“number”不是有效的警告号
  • CS1692数字无效
  • CS1694为预处理器指令指定的文件名无效。文件名太长或无效的文件名
  • CS1695: 无效的 #pragma 校验和语法;应为 #pragma 校验和 "filename" "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" "XXXX..."
  • CS1696预期单行注释或行尾终止符
  • CS1709为预处理器指令指定的文件名为空
  • CS7009无法在文件的第一个令牌之后使用 #r
  • CS7010应有带引号的文件名
  • CS7011脚本中仅允许 #r
  • CS8097#load 仅允许在脚本中
  • CS8098在文件中的首个标记后无法使用 #load
  • CS8938#line 指令值缺失或范围不足
  • CS8939#line 指令结束位置必须大于或等于起始位置
  • CS8996预处理器指令中不允许原始字符串文本
  • CS9028#line span 指令需要在第一个括号前、字符偏移前和文件名之前空格
  • CS9297#: 指令不能放在文件中第一个标记之后
  • CS9298#: 指令只能在基于文件的程序中使用(-features:FileBasedProgram
  • CS9299#: 指令不能在 #if 指令之后
  • CS9314#! 指令只能在脚本或基于文件的程序中使用

预处理器指令语法无效

  • CS1024预期预处理器指令
  • CS1025预计需要单行注释或行尾
  • CS1027需要 #endif 指令
  • CS1028意外的预处理器指令
  • CS1038预期 #endregion 指令
  • CS1040预处理器指令必须显示为行上的第一个非空格字符
  • CS1517预处理器表达式无效
  • CS1633无法识别 #pragma 指令
  • CS1696预期出现单行注释或行末注释
  • CS8996预处理器指令中不允许原始字符串文本

这些错误指示你对 预处理器指令使用了无效的语法。 常见原因包括:

  • 使用无法识别的指令(CS1024,CS1633)在 # 之后。
  • 在指令行中包含多行注释(适用于 CS1025 和 CS1696)。
  • 在意外位置(CS1028)中使用指令。
  • 缺少所需的匹配指令(CS1027、CS1038)。
  • 未在文件中第一个标记处定义或取消定义符号(CS1032)
  • 不要将指令作为第一个标记放在行(CS1040) 上。
  • 在条件编译中使用无效的表达式(CS1517)。
  • 在预处理器指令中使用原始字符串文本(CS8996)。

CS1024 示例 - 需要预处理器指令:

#import System   // CS1024 - "import" is not a valid directive

CS1025 示例 - 应使用单行注释或行尾:

#if true /* hello  
*/   // CS1025 - multiline comment not allowed
#endif

CS1027 示例 - 预计需要 #endif 指令:

#if true   // CS1027 - missing #endif
class Test { }

CS1028 示例 - 意外的预处理器指令:

#endif   // CS1028 - no matching #if

CS1032 示例 - #define#undef 预处理器指令必须出现在其他令牌之前:

/* Comment */ 
#define X   // CS1032 - directive not first token in file

CS1038 示例 - 需要 #endregion 指令:

#region testing
class Test { }
// CS1038 - missing #endregion

CS1040 示例 - 预处理器指令必须显示为第一个非空格字符:

/* Comment */ #define X   // CS1040 - directive not first on line

CS1517 示例 - 预处理器表达式无效:

#if 1           // CS1517 - numeric literals not allowed
#endif
#if ~symbol     // CS1517 - bitwise operators not allowed  
#endif

CS1633 示例 - 无法识别 #pragma 指令:

#pragma unknown  // CS1633 - "unknown" is not a valid pragma

CS8996 示例 - 预处理器指令中不允许原始字符串文本:

// CS8996.cs
#pragma checksum """raw_string""" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "hash"  // CS8996
class Test { }

若要修复此错误,请使用常规字符串文本:

#pragma checksum "filename.cs" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "hash"  // OK
class Test { }

若要修复这些错误,请确保预处理器指令遵循 预处理器指令文档中介绍的正确语法规则。

#error 和 #warning 指令错误

  • CS1029#error:“text”
  • CS1030#warning: 'text'
  • CS1634预期禁用或还原
  • CS1635无法还原警告“警告代码”,因为它已全局禁用
  • CS1691“number”不是有效的警告号
  • CS1692数字无效

当编译器处理#error#warning#pragma warning指令时,会发生这些错误。 这些指令允许在编译和控制警告行为期间生成自定义错误和警告消息。

CS1029 显示使用 #error 指令定义的错误的文本:

// CS1029.cs
class Sample
{
   static void Main()
   {
      #error Let's give an error here   // CS1029
   }
}

编译产生以下输出:

example.cs(9,8): error CS1029: #error: 'Let's give an error here   // CS1029  '

CS1030 显示使用 #warning 指令定义的警告文本:

// CS1030.cs
class Sample
{
   static void Main()
   {
      #warning Let's give a warning here
   }
}

编译产生以下输出:

example.cs(6,16): warning CS1030: #warning: 'Let's give a warning here'

#pragma warning子句格式不正确,例如省略了“禁用”或“还原”时,就会发生CS1634错误。

// CS1634.cs
// compile with: /W:1

#pragma warning   // CS1634
// Try this instead:
// #pragma warning disable 0219

class MyClass
{
  public static void Main()
  {
  }
}

CS1635 当您使用命令行选项或项目设置来全局禁用警告时发生,但使用#pragma warning restore试图恢复该警告:

// CS1635.cs
// compile with: /w:1 /nowarn:162

enum MyEnum {one=1,two=2,three=3};

class MyClass
{
    public static void Main()
    {
#pragma warning disable 162

    if (MyEnum.three == MyEnum.two)
        System.Console.WriteLine("Duplicate");

#pragma warning restore 162  // CS1635
    }
}

当传递给指令的数字不是有效的警告号时,会发生 #pragma warning

// CS1691.cs
public class C
{
    int i = 1;
    public static void Main()
    {
        C myC = new C();
#pragma warning disable 151  // CS1691
// Try the following line instead:
// #pragma warning disable 1645
        myC.i++;
#pragma warning restore 151  // CS1691
// Try the following line instead:
// #pragma warning restore 1645
    }
}

CS1692 发生在预处理器指令中的数字(如 #pragma#line 无效)时,因为它太大、格式错误或包含非法字符:

// CS1692.cs

#pragma warning disable a  // CS1692
// Try this instead:
// #pragma warning disable 1691

class A
{
    static void Main()
    {
    }
}

这些指令对于条件编译方案非常有用,你希望提醒开发人员有关代码中的特定条件,或控制编译期间显示哪些警告。 有关使用这些指令的详细信息,请参阅 预处理器指令文档#pragma 警告

#line 和文件指令错误

  • CS1560为预处理器指令指定的文件名无效。文件名太长或无效的文件名
  • CS1576为 #line 指令指定的行号缺失或无效
  • CS1578应提供文件名、单行注释或行尾
  • CS1694为预处理器指令指定的文件名无效。文件名太长或无效的文件名
  • CS1695无效的 #pragma 校验和语法;应为 #pragma 校验和 "filename" "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" "XXXX..."
  • CS1709为预处理器指令指定的文件名为空
  • CS8938#line 指令值缺失或范围不足
  • CS8939#line 指令结束位置必须大于或等于起始位置
  • CS9028#line span 指令在第一个括号前、字符偏移前和文件名之前需要空格

这些错误表示指令或与文件相关的预处理器指令的用法#line不正确。 常见原因包括:

  • 无效或缺少文件名(CS1560、CS1694、CS1709)。
  • 行号格式或值不正确(CS1576、CS8938、CS8939)。
  • 缺少文件名和注释的正确语法(CS1578)。
  • 语法格式错误 #pragma checksum(CS1695)。
  • 跨度指令中的 #line 间距不正确(CS9028)。

CS1560/CS1694 示例 - 指定的文件名无效:

#line 100 "MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890MyFile1234567890.txt"   // CS1560/CS1694 - filename too long

CS1576 示例 - 行号缺失或无效:

#line "abc.sc"         // CS1576 - missing line number
#line abc "file.cs"    // CS1576 - invalid line number format

CS1578 示例 - 应为文件名、注释或行尾:

#line 101 abc.cs   // CS1578 - filename not quoted

CS1695 示例 - #pragma 校验和语法无效:

#pragma checksum "12345"  // CS1695 - missing GUID and checksum

CS1709 示例 - 空文件名:

#pragma checksum "" "{406EA660-64CF-4C82-B6F0-42D48172A799}" ""  // CS1709 - empty filename

CS8938 示例 - #line 指令值缺失或范围不足:

#line   // CS8938 - missing value
#line 0  // CS8938 - out of range (must be 1-16,707,566)

CS8939 示例 - #line 结束位置错误:

#line (1, 10) - (1, 5) "file.cs"  // CS8939 - end column < start column

CS9028 示例 - #line span 指令间距:

#line(1, 1) - (1, 10)"file.cs"  // CS9028 - missing spaces

若要修复这些错误,请确保指令 #line 和与文件相关的预处理器指令遵循正确的语法,如 预处理器指令文档中所述。

基于文件的应用指令使用不正确

  • CS9297#: 指令不能在文件中的第一个令牌之后
  • CS9298#: 指令只能在基于文件的程序中使用(-features:FileBasedProgram
  • CS9299#:指令不能在指令之后#if
  • CS9314#! 指令只能在脚本或基于文件的程序中使用

这些错误指示错误地使用了 #: 基于文件的应用的指令。 您可以在关于预处理器指令的文章中,文件型应用部分,了解更多关于这些指令的语法。 或者,可以按照基于文件的应用的 教程 来浏览基于文件的应用。

文件包含script.cs指令

以下错误指示编译的 C# 文件中 script.cs 语法:

  • CS7009无法在文件中的第一个令牌后使用 #r
  • CS7010应有带引号的文件名
  • CS7011脚本中仅允许 #r
  • CS8097脚本中仅允许 #load

编译的 C# 中不支持这些指令。 必须删除它们,或使用 script.cs