前置處理器錯誤和警告

編譯器會產生下列錯誤,係由於不正確使用前置處理器指令:

  • CS1024: 預期預處理器指令
  • CS1025: 預期單行註解或行結尾
  • CS1027: 預期 #endif 指令
  • CS1028: 非預期的前置處理器指示詞
  • CS1029: #error:「文字」
  • CS1030:#warning:「文字」
  • CS1032: 無法在檔案的第一個標記之後定義/取消定義前置處理器符號
  • CS1038: 預期 #endregion 指令
  • CS1040: 前置處理器指示詞必須顯示為行上的第一個非空格字元
  • CS1517: 無效的前置處理器運算式
  • CS1560: 為前置處理器指示詞指定的檔名無效。檔案名稱太長或不是有效的檔案名稱
  • CS1576: 在 #line 指令中指定的行號遺失或無效
  • CS1578: 預期檔案名稱、單行註解或行尾
  • CS1633: 無法辨識的 #pragma 指示詞
  • CS1634: 預期停用或還原
  • CS1635: 無法還原警告「警告代碼」,因為它已全域停用
  • CS1691:「數字」不是有效的警告號碼
  • CS1692: 號碼無效
  • CS1694: 針對前置處理器指示詞指定的檔名無效。檔案名稱太長或不是有效的檔案名稱
  • CS1695: #pragma 校驗碼語法無效,應該為 #pragma 校驗碼 “filename” “{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}” “XXXX...”
  • CS1696: 預期單行註解或行尾
  • CS1709: 為前置處理器指示詞指定的檔名是空的
  • CS7009: 檔案中的第一個標記之後不能使用 #r
  • CS7010: 預期會以引號括住的檔案名稱
  • CS7011: 只有腳本中才允許 #r
  • CS8097: 只有腳本中才允許 #load
  • CS8098:無法在檔案中第一個標記之後使用 #load
  • CS8301: 預處理符號名稱無效;「符號名稱」並非有效的識別碼
  • CS8938:#line 指令值遺失或超出範圍
  • CS8939: #line 指示詞結束位置必須大於或等於起始位置
  • CS8996: 預處理器指令中不允許使用原始字串字面值
  • CS9028:#line span 指示詞需要在第一個括弧、字元位移和檔名之前加上空格
  • CS9297: #: 指令不能位於檔案中的第一個語彙單元後面
  • CS9298: #: 指令只能用於基於檔案的應用程式(-features:FileBasedProgram)
  • CS9299:#:指令不能在#if指令之後
  • CS9314: #! 指令只能用於腳本或基於檔案的應用程式
  • CS9378:「#!」必須是檔案第一行的第一個字元。

前置處理器指引語法無效

  • CS1024: 預期前置處理器指令
  • CS1025: 預期單行註解或注释結束符
  • CS1027:預期指令為 #endif
  • CS1028: 非預期的前置處理器指示詞
  • CS1032: 檔案中第一個標記後無法定義/取消定義預處理器符號
  • CS1038: 預期 #endregion 指令
  • CS1040: 前置處理器指示詞必須顯示為行上的第一個非空格字元
  • CS1517: 無效的前置處理器運算式
  • CS1633: 無法辨識的 #pragma 指示詞
  • CS1696: 預期為單行註解或結束行
  • CS8996: 預處理器指令中不允許原始字串常值

這些錯誤表示您對 前置處理器指示詞使用了無效的語法。 常見原因包括:

  • 在 # 之後使用未識別的指示 (CS1024, CS1633)。
  • 包括指令行上的多行註解 (CS1025、CS1696)。
  • 在非預期的位置使用指令 (CS1028)。
  • 遺漏必要的比對指示詞 (CS1027、CS1038)。
  • 在檔案中的第一個標記(CS1032)後方放置 #define or #undef 指令。
  • 未將指令放在行首的第一個符號(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 前置處理器指令必須出現在其他標誌之前:

class Test { }
#define X   // CS1032 - directive appears after the first token

要修正此錯誤,請將 all #define 和 #undef 指令置於檔案中第一個標記之前:

#define X
#undef Y
class Test { }

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 { }

若要修正這些錯誤,請確定您的預處理器指引遵循前 置處理器指引檔案中所述的正確語法規則。

無效的預處理器符號名稱

  • CS8301: 預處理符號名稱無效;「符號名稱」並非有效的識別碼

程式化建立 CSharpParseOptions 時,請將每個條件編譯符號都設定為一個識別碼形狀的名稱。 第一個字元必須在 C# 識別碼的開頭有效,其餘字元必須是有效的識別字元。 Roslyn 也接受將關鍵字文字串作為符號名稱,但請勿加上 @ 前綴。 不要包含空白、標點符號(例如 . 或 -)、指派運算式(例如 FEATURE=1),或完整的條件運算式。

預處理符號僅記錄其名稱是否被定義。 它不會儲存價值。 若透過 DefineConstants 專案屬性或 -define 編譯器選項提供的無效名稱,則會產生 CS2029 ;詳見 DefineConstants。

#error 和 #warning 指令錯誤

  • CS1029: #error:「文字」
  • CS1030: #warning:「文字」
  • 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'

CS1634 會在子句格式不正確時 #pragma warning 發生,例如省略停用或還原時:

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

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

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

當您使用或專案設定全局停用警告,但嘗試使用/nowarn還原該警告時,就會發生#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
    }
}

當在預處理器指令中的數字(例如 和 #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 checksum 語法無效;應為 #pragma checksum "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)。
  • span 指令中的 #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 範圍指令的空格設置:

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

若要修正這些錯誤,請確定您的 #line 指示詞和檔案相關的前置處理器指示詞遵循前 置處理器指示詞文件中所述的正確語法。

不正確使用檔案型應用程式指令

  • CS9297: #: 指令不能出現在檔案中的第一個語法單位之後
  • CS9298: #: 指令只能用於基於檔案的應用程式(-features:FileBasedProgram)
  • CS9299:#:指令不能位於#if指令之後
  • CS9314: #! 指令只能用於腳本或基於檔案的應用程式
  • CS9378:「#!」必須是檔案第一行的第一個字元。

這些錯誤表示你錯誤地使用了 #: 或 #! 指示詞。 想了解更多這些指令的語法,請參閱檔案式應用程式章節中關於 預處理器指令 的文章。 或者,你也可以透過跟著檔案式應用程式的 教學 來探索檔案式應用程式。

shebang(#!)用來指定指令碼或檔案型應用程式的執行程式。 將它放在第一行的第一個字元上,置於任何空白、註解或空白行之前(CS9378);請參閱 檔案式應用程式指令指引。

檔案包含 script.cs 指令

以下錯誤表示 C# 腳本指令的錯誤使用或放置錯誤:

  • CS7009: 檔案中第一個語彙單元後不可以使用 #r
  • CS7010:預期為以引號括住的檔案名稱
  • CS7011: 只有腳本中才允許 #r
  • CS8097: 腳本中只允許 #load
  • CS8098:無法在檔案中的第一個語彙基元之後使用 #load

在 C# 指令碼(.csx)中,權杖後面的 #load 指示詞會產生 CS8098:

System.Console.WriteLine("This is the first token.");
#load "helpers.csx" // CS8098

要修正 CS8098,請將腳本中每個 #load 指令置於每個標記之前:

#load "helpers.csx"
System.Console.WriteLine("The directive precedes the first token.");

在一般 C# 原始碼檔案中(.cs),不允許使用 #load。 該相關病症會產生 CS8097,而非 CS8098。 從一般原始碼檔案移除 #load 。