Sözcük yapısıLexical structure

ProgramlarPrograms

C# Program _, bilinen bir veya daha fazla _kaynak dosyadan_ oluşur. Bu bir veya daha fazla, bilinen adıyla _ derleme birimleri (derleme birimleri)A C# program _ consists of one or more _source files_, known formally as _ compilation units (Compilation units). Kaynak dosya, bir dizi Unicode karakterden oluşan sıralı bir dizidir.A source file is an ordered sequence of Unicode characters. Kaynak dosyaların bir dosya sistemindeki dosyalarla genellikle bire bir yazışmaları vardır, ancak bu yazışma gerekli değildir.Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. En fazla taşınabilirlik için, bir dosya sistemindeki dosyaların UTF-8 kodlaması ile kodlanması önerilir.For maximal portability, it is recommended that files in a file system be encoded with the UTF-8 encoding.

Kavramsal olarak bakıldığında, bir program üç adım kullanılarak derlenir:Conceptually speaking, a program is compiled using three steps:

  1. Bir dosyayı belirli bir karakter topluluğunun ve kodlama düzeninden bir Unicode karakter dizisine dönüştüren dönüştürme.Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters.
  2. Unicode giriş karakterlerinden oluşan bir akışı belirteç akışına çeviren sözcük temelli analiz.Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens.
  3. Belirteçlerin akışını yürütülebilir koda çeviren sözdizimsel analiz.Syntactic analysis, which translates the stream of tokens into executable code.

DilbilgisindeGrammars

Bu belirtim, C# programlama dilinin sözdizimini iki dilmars kullanarak gösterir.This specification presents the syntax of the C# programming language using two grammars. *Sözlü dilbilgisi _ (sözlü dilbilgisi), Unicode karakterlerinin form satır sonlandırıcılar, beyaz boşluk, açıklama, belirteç ve ön işleme yönergeleri ile nasıl birleştirildiğini tanımlar.The *lexical grammar _ (Lexical grammar) defines how Unicode characters are combined to form line terminators, white space, comments, tokens, and pre-processing directives. _ Sözdizimsel dilbilgisi * (sözdizimsel dilbilgisi), sözlü dilbilgisinde elde edilen belirteçlerin C# programları için nasıl birleştirileceğini tanımlar.The _ syntactic grammar* (Syntactic grammar) defines how the tokens resulting from the lexical grammar are combined to form C# programs.

Dilbilgisi gösterimiGrammar notation

Sözlü ve sözdizimsel dilbilgisinde, ANTLR dilbilgisi aracının gösterimi kullanılarak Backus-Naur form sunulmaktadır.The lexical and syntactic grammars are presented in Backus-Naur form using the notation of the ANTLR grammar tool.

Sözcük temelli dil bilgisiLexical grammar

C# ' nin sözcük dilbilgisi açıklaması, sözcük temelli analiz, belirteçlerve önceden işleme yönergeleriylesunulmaktadır.The lexical grammar of C# is presented in Lexical analysis, Tokens, and Pre-processing directives. Sözcük tabanlı dilbilgisinin Terminal sembolleri, Unicode karakter kümesinin karakterleridir ve sözlü dilbilgisi, karakterlerin belirteç (belirteçler), beyaz boşluk (beyaz boşluk), açıklamalar (açıklamalar) ve önceden işleme yönergeleri (ön işleme yönergeleri) için nasıl birleştirildiğini belirtir.The terminal symbols of the lexical grammar are the characters of the Unicode character set, and the lexical grammar specifies how characters are combined to form tokens (Tokens), white space (White space), comments (Comments), and pre-processing directives (Pre-processing directives).

Bir C# programındaki her kaynak dosya, sözlü dilbilgisinde (sözlü analiz) gelen giriş üretimine uygun olmalıdır.Every source file in a C# program must conform to the input production of the lexical grammar (Lexical analysis).

Söz dizimsel dil bilgisiSyntactic grammar

C# ' nin sözdizimsel dilbilgisi, bu bölümü izleyen bölümlerde ve appendıces içinde sunulmuştur.The syntactic grammar of C# is presented in the chapters and appendices that follow this chapter. Sözdizimsel dilbilgisinde Terminal sembolleri, sözlü dilbilgisi tarafından tanımlanan belirteçlerdir ve sözdizimsel dilbilgisi belirteçleri C# programları için nasıl birleştirildiğini belirtir.The terminal symbols of the syntactic grammar are the tokens defined by the lexical grammar, and the syntactic grammar specifies how tokens are combined to form C# programs.

Bir C# programındaki her kaynak dosyası, sözdizimsel dilbilgisi (derleme birimleri) compilation_unit üretimine uymalıdır.Every source file in a C# program must conform to the compilation_unit production of the syntactic grammar (Compilation units).

Sözcük temelli analizLexical analysis

Giriş üretimi bir C# kaynak dosyasının sözlü yapısını tanımlar.The input production defines the lexical structure of a C# source file. Bir C# programındaki her kaynak dosya, bu sözcük temelli dilbilgisi üretimine uygun olmalıdır.Each source file in a C# program must conform to this lexical grammar production.

input
    : input_section?
    ;

input_section
    : input_section_part+
    ;

input_section_part
    : input_element* new_line
    | pp_directive
    ;

input_element
    : whitespace
    | comment
    | token
    ;

Beş temel öğe, bir C# kaynak dosyasının sözlü yapısını yapar: satır sonlandırıcılar (satır sonlandırıcılar), boşluk (boşluk), açıklamalar (açıklamalar), belirteçler (belirteçler) ve önceden işleme yönergeleri (ön işleme yönergeleri).Five basic elements make up the lexical structure of a C# source file: Line terminators (Line terminators), white space (White space), comments (Comments), tokens (Tokens), and pre-processing directives (Pre-processing directives). Bu temel öğelerin yalnızca belirteçleri, C# programının sözdizimsel dilbilgisinde (sözdizimsel dilbilgisi) önemlidir.Of these basic elements, only tokens are significant in the syntactic grammar of a C# program (Syntactic grammar).

Bir C# kaynak dosyasının sözcük işleme işlemi, dosyayı sözdizimsel Analize veren bir belirteç dizisine düşürmektir.The lexical processing of a C# source file consists of reducing the file into a sequence of tokens which becomes the input to the syntactic analysis. Satır sonlandırıcılar, boşluk ve açıklamalar ayrı belirteçlere sunabilir ve önceden işleme yönergeleri kaynak dosyanın bölümlerinin atlanmasına neden olabilir, ancak bu sözcük temelli öğelerin bir C# programının sözdizimsel yapısını etkilemez.Line terminators, white space, and comments can serve to separate tokens, and pre-processing directives can cause sections of the source file to be skipped, but otherwise these lexical elements have no impact on the syntactic structure of a C# program.

Enterpolasyonlu dize sabit değerleri (enterpolasyonlu dize sabit değerleri), ilk olarak sözlü analiz tarafından üretilir, ancak tüm enterpolasyonlu tüm dize sabit değerleri çözümlenene kadar çok sayıda giriş öğesine bölünmüştür.In the case of interpolated string literals (Interpolated string literals) a single token is initially produced by lexical analysis, but is broken up into several input elements which are repeatedly subjected to lexical analysis until all interpolated string literals have been resolved. Elde edilen belirteçler daha sonra sözdizimsel Analize giriş olarak görev yapar.The resulting tokens then serve as input to the syntactic analysis.

Birçok sözlü dilbilgisi üretimi, bir kaynak dosyadaki bir karakter dizisiyle eşleşiyorsa, sözcük işleme her zaman mümkün olan en uzun sözlü öğeyi oluşturur.When several lexical grammar productions match a sequence of characters in a source file, the lexical processing always forms the longest possible lexical element. Örneğin, // sözcük sırası tek satırlık açıklamanın başlangıcında işlenir çünkü bu, sözlü öğe tek bir / belirteçten daha uzun.For example, the character sequence // is processed as the beginning of a single-line comment because that lexical element is longer than a single / token.

Satır sonlandırıcılarLine terminators

Satır sonlandırıcılar, bir C# kaynak dosyasının karakterlerini çizgilere böler.Line terminators divide the characters of a C# source file into lines.

new_line
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Carriage return character (U+000D) followed by line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

Dosya sonu işaretçileri ekleyen kaynak kodu düzenlemeyle uyumluluk için ve bir kaynak dosyanın düzgün bir şekilde sonlandırılmış satırlar halinde görüntülenmesini sağlamak için, bir C# programındaki her kaynak dosyasına sırayla aşağıdaki dönüşümler uygulanır:For compatibility with source code editing tools that add end-of-file markers, and to enable a source file to be viewed as a sequence of properly terminated lines, the following transformations are applied, in order, to every source file in a C# program:

  • Kaynak dosyanın son karakteri bir Control-Z karakteri ( U+001A ) ise, bu karakter silinir.If the last character of the source file is a Control-Z character (U+001A), this character is deleted.
  • Kaynak dosya U+000D boş değilse ve kaynak dosyanın son karakteri bir satır başı ( U+000D ), bir satır akışı ( U+000A ), satır ayırıcı ( U+2028 ) veya paragraf ayırıcı () değilse, kaynak dosyanın sonuna bir satır başı karakteri () eklenir U+2029 .A carriage-return character (U+000D) is added to the end of the source file if that source file is non-empty and if the last character of the source file is not a carriage return (U+000D), a line feed (U+000A), a line separator (U+2028), or a paragraph separator (U+2029).

YorumlarComments

İki açıklama biçimi desteklenir: tek satırlı açıklamalar ve sınırlandırılmış açıklamalar.Two forms of comments are supported: single-line comments and delimited comments.\ Tek satır açıklamaları _ karakterlerle başlayın // ve kaynak satırın sonuna kadar genişletin.\ Single-line comments _ start with the characters // and extend to the end of the source line. _Sınırlandırılmış açıklamalar_ karakterlerle başlar /_ ve karakterlerle biter */ .Delimited comments start with the characters /_ and end with the characters */. Sınırlandırılmış açıklamalar birden çok satıra yayılabilir.Delimited comments may span multiple lines.

comment
    : single_line_comment
    | delimited_comment
    ;

single_line_comment
    : '//' input_character*
    ;

input_character
    : '<Any Unicode character except a new_line_character>'
    ;

new_line_character
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

delimited_comment
    : '/*' delimited_comment_section* asterisk+ '/'
    ;

delimited_comment_section
    : '/'
    | asterisk* not_slash_or_asterisk
    ;

asterisk
    : '*'
    ;

not_slash_or_asterisk
    : '<Any Unicode character except / or *>'
    ;

Açıklamalar iç içe yerleştirilmez.Comments do not nest. Karakter dizileri ve /* */ bir yorum içinde özel anlamı yoktur ve // karakter dizileri ve // /* ayrılmış bir açıklama içinde özel bir anlamı yoktur.The character sequences /* and */ have no special meaning within a // comment, and the character sequences // and /* have no special meaning within a delimited comment.

Açıklamalar karakter ve dize değişmez değerleri içinde işlenmez.Comments are not processed within character and string literals.

ÖrnekteThe example

/* Hello, world program
   This program writes "hello, world" to the console
*/
class Hello
{
    static void Main() {
        System.Console.WriteLine("hello, world");
    }
}

sınırlandırılmış bir açıklama bulunmaktadır.includes a delimited comment.

ÖrnekteThe example

// Hello, world program
// This program writes "hello, world" to the console
//
class Hello // any name will do for this class
{
    static void Main() { // this method must be named "Main"
        System.Console.WriteLine("hello, world");
    }
}

birkaç tek satırlı açıklama gösterilmektedir.shows several single-line comments.

BoşlukWhite space

Boşluk karakteri, yatay sekme karakteri, dikey sekme karakteri ve form besleme karakteri olan Unicode sınıf ZS (boşluk karakterini de içerir) ile herhangi bir karakter olarak tanımlanır.White space is defined as any character with Unicode class Zs (which includes the space character) as well as the horizontal tab character, the vertical tab character, and the form feed character.

whitespace
    : '<Any character with Unicode class Zs>'
    | '<Horizontal tab character (U+0009)>'
    | '<Vertical tab character (U+000B)>'
    | '<Form feed character (U+000C)>'
    ;

BelirteçlerTokens

Birkaç tür belirteç vardır: tanımlayıcılar, anahtar sözcükler, sabit değerler, işleçler ve noktalama işaretleri.There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators. Boşluk ve açıklamalar belirteçler değildir, ancak belirteçler için ayırıcılar işlevi görür.White space and comments are not tokens, though they act as separators for tokens.

token
    : identifier
    | keyword
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | interpolated_string_literal
    | operator_or_punctuator
    ;

Unicode karakter kaçış dizileriUnicode character escape sequences

Unicode karakter kaçış dizisi bir Unicode karakteri temsil eder.A Unicode character escape sequence represents a Unicode character. Unicode karakter kaçış dizileri tanımlayıcılarda (tanımlayıcılar), karakter sabit değerlerinde (karakter sabitdeğerleri) ve normal dize değişmez değerlerinde (dize sabit değerleri) işlenir.Unicode character escape sequences are processed in identifiers (Identifiers), character literals (Character literals), and regular string literals (String literals). Unicode karakter kaçış başka bir konumda işlenmez (örneğin, bir işleç, noktalama veya anahtar sözcük oluşturmak için).A Unicode character escape is not processed in any other location (for example, to form an operator, punctuator, or keyword).

unicode_escape_sequence
    : '\\u' hex_digit hex_digit hex_digit hex_digit
    | '\\U' hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
    ;

Unicode kaçış sırası, " \u " veya "" karakterlerinden sonra onaltılık sayı tarafından oluşturulan tek Unicode karakteri temsil eder \U .A Unicode escape sequence represents the single Unicode character formed by the hexadecimal number following the "\u" or "\U" characters. C#, karakter ve dize değerlerinde Unicode kod noktalarının 16 bitlik bir kodlamasını kullandığından, bir karakter sabit değerinde U + 10000-U + 10FFFF aralığındaki bir Unicode karaktere izin verilmez ve bir dize sabit değerinde Unicode vekil çifti kullanılarak temsil edilir.Since C# uses a 16-bit encoding of Unicode code points in characters and string values, a Unicode character in the range U+10000 to U+10FFFF is not permitted in a character literal and is represented using a Unicode surrogate pair in a string literal. 0x10FFFF üzerinde kod noktaları olan Unicode karakterler desteklenmez.Unicode characters with code points above 0x10FFFF are not supported.

Birden çok çeviri gerçekleştirilmez.Multiple translations are not performed. Örneğin, "" dize değişmez değeri "" \u005Cu005C yerine "" ile eşdeğerdir \u005C \ .For instance, the string literal "\u005Cu005C" is equivalent to "\u005C" rather than "\". Unicode değeri \u005C " \ " karakteridir.The Unicode value \u005C is the character "\".

ÖrnekteThe example

class Class1
{
    static void Test(bool \u0066) {
        char c = '\u0066';
        if (\u0066)
            System.Console.WriteLine(c.ToString());
    }        
}

\u0066"" harfi için kaçış sırası olan, öğesinin birkaç kullanımını gösterir f .shows several uses of \u0066, which is the escape sequence for the letter "f". Program şu şekilde eşdeğerdirThe program is equivalent to

class Class1
{
    static void Test(bool f) {
        char c = 'f';
        if (f)
            System.Console.WriteLine(c.ToString());
    }        
}

TanımlayıcılarIdentifiers

Bu bölümde verilen tanımlayıcılara yönelik kurallar tam olarak Unicode standart ek 31 tarafından Önerilenlere karşılık gelir, ancak alt çizgi ilk karakter olarak izin verilir (C programlama dilinde geleneksel olarak), tanımlayıcılarda Unicode kaçış dizilerine izin verilir ve " @ " karakteri, anahtar sözcüklerin tanımlayıcı olarak kullanılmasına olanak tanımak için önek olarak izin verilir.The rules for identifiers given in this section correspond exactly to those recommended by the Unicode Standard Annex 31, except that underscore is allowed as an initial character (as is traditional in the C programming language), Unicode escape sequences are permitted in identifiers, and the "@" character is allowed as a prefix to enable keywords to be used as identifiers.

identifier
    : available_identifier
    | '@' identifier_or_keyword
    ;

available_identifier
    : '<An identifier_or_keyword that is not a keyword>'
    ;

identifier_or_keyword
    : identifier_start_character identifier_part_character*
    ;

identifier_start_character
    : letter_character
    | '_'
    ;

identifier_part_character
    : letter_character
    | decimal_digit_character
    | connecting_character
    | combining_character
    | formatting_character
    ;

letter_character
    : '<A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    | '<A unicode_escape_sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    ;

combining_character
    : '<A Unicode character of classes Mn or Mc>'
    | '<A unicode_escape_sequence representing a character of classes Mn or Mc>'
    ;

decimal_digit_character
    : '<A Unicode character of the class Nd>'
    | '<A unicode_escape_sequence representing a character of the class Nd>'
    ;

connecting_character
    : '<A Unicode character of the class Pc>'
    | '<A unicode_escape_sequence representing a character of the class Pc>'
    ;

formatting_character
    : '<A Unicode character of the class Cf>'
    | '<A unicode_escape_sequence representing a character of the class Cf>'
    ;

Yukarıda belirtilen Unicode karakter sınıfları hakkında daha fazla bilgi için bkz. Unicode standart, sürüm 3,0, Bölüm 4,5.For information on the Unicode character classes mentioned above, see The Unicode Standard, Version 3.0, section 4.5.

Geçerli tanımlayıcıların örnekleri şunlardır " identifier1 ", " _identifier2 " ve " @if ".Examples of valid identifiers include "identifier1", "_identifier2", and "@if".

Uyumlu bir programdaki tanımlayıcı, Unicode standart ek 15 tarafından tanımlanan, Unicode normalleştirme biçimi C tarafından tanımlanan kurallı biçimde olmalıdır.An identifier in a conforming program must be in the canonical format defined by Unicode Normalization Form C, as defined by Unicode Standard Annex 15. Normalleştirme biçimi C 'de olmayan bir tanımlayıcı ile karşılaştığın davranışı uygulama tanımlı; Ancak, bir tanılama gerekli değildir.The behavior when encountering an identifier not in Normalization Form C is implementation-defined; however, a diagnostic is not required.

"" Ön eki, @ diğer programlama dilleriyle arabirim oluştururken yararlı olan tanımlayıcı olarak anahtar kelimelerin kullanılmasını sağlar.The prefix "@" enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. Karakter @ aslında tanımlayıcının bir parçası değildir, bu nedenle tanımlayıcı, ön ek olmadan diğer dillerde normal tanımlayıcı olarak görülemeyebilir.The character @ is not actually part of the identifier, so the identifier might be seen in other languages as a normal identifier, without the prefix. Ön eke sahip bir tanımlayıcıya @ , tam tanımlayıcı denir.An identifier with an @ prefix is called a verbatim identifier. @Anahtar sözcük olmayan tanımlayıcılar için ön ek kullanılmasına izin verilir, ancak stil açısından kesinlikle önerilmez.Use of the @ prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style.

Örnek:The example:

class @class
{
    public static void @static(bool @bool) {
        if (@bool)
            System.Console.WriteLine("true");
        else
            System.Console.WriteLine("false");
    }    
}

class Class1
{
    static void M() {
        cl\u0061ss.st\u0061tic(true);
    }
}

"" adlı bir class parametre alan "" adlı statik bir yöntemle "" adlı bir sınıf tanımlar static bool .defines a class named "class" with a static method named "static" that takes a parameter named "bool". Anahtar kelimelerinde Unicode kaçışlara izin verilmemesine, " cl\u0061ss " belirtecinin bir tanımlayıcı olduğuna ve "" ile aynı tanımlayıcıda olduğuna unutmayın @class .Note that since Unicode escapes are not permitted in keywords, the token "cl\u0061ss" is an identifier, and is the same identifier as "@class".

İki tanımlayıcı, aşağıdaki dönüşümler uygulandıktan sonra aynı olursa, sırasıyla aynı kabul edilir:Two identifiers are considered the same if they are identical after the following transformations are applied, in order:

  • " @ " Kullanılırsa, ' "öneki kaldırılır.The prefix "@", if used, is removed.
  • Her unicode_escape_sequence karşılık gelen Unicode karakteriyle dönüştürülür.Each unicode_escape_sequence is transformed into its corresponding Unicode character.
  • Tüm formatting_character kaldırılır.Any formatting_character s are removed.

Art arda iki alt çizgi karakteri ( U+005F ) içeren tanımlayıcılar, uygulama tarafından kullanılmak üzere ayrılmıştır.Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation. Örneğin, bir uygulama iki alt çizgi ile başlayan genişletilmiş anahtar sözcükler sağlayabilir.For example, an implementation might provide extended keywords that begin with two underscores.

Anahtar sözcüklerKeywords

Anahtar sözcüğü , ayrılmış karakterlerin tanımlayıcı benzeri bir dizidir ve karakter tarafından ön çıkması dışında bir tanımlayıcı olarak kullanılamaz @ .A keyword is an identifier-like sequence of characters that is reserved, and cannot be used as an identifier except when prefaced by the @ character.

keyword
    : 'abstract' | 'as'       | 'base'       | 'bool'      | 'break'
    | 'byte'     | 'case'     | 'catch'      | 'char'      | 'checked'
    | 'class'    | 'const'    | 'continue'   | 'decimal'   | 'default'
    | 'delegate' | 'do'       | 'double'     | 'else'      | 'enum'
    | 'event'    | 'explicit' | 'extern'     | 'false'     | 'finally'
    | 'fixed'    | 'float'    | 'for'        | 'foreach'   | 'goto'
    | 'if'       | 'implicit' | 'in'         | 'int'       | 'interface'
    | 'internal' | 'is'       | 'lock'       | 'long'      | 'namespace'
    | 'new'      | 'null'     | 'object'     | 'operator'  | 'out'
    | 'override' | 'params'   | 'private'    | 'protected' | 'public'
    | 'readonly' | 'ref'      | 'return'     | 'sbyte'     | 'sealed'
    | 'short'    | 'sizeof'   | 'stackalloc' | 'static'    | 'string'
    | 'struct'   | 'switch'   | 'this'       | 'throw'     | 'true'
    | 'try'      | 'typeof'   | 'uint'       | 'ulong'     | 'unchecked'
    | 'unsafe'   | 'ushort'   | 'using'      | 'virtual'   | 'void'
    | 'volatile' | 'while'
    ;

Dilbilgisinde bazı yerlerde, belirli tanımlayıcıların özel anlamları vardır ancak anahtar sözcük değildir.In some places in the grammar, specific identifiers have special meaning, but are not keywords. Bu tür tanımlayıcılar bazen "bağlamsal anahtar sözcükler" olarak adlandırılır.Such identifiers are sometimes referred to as "contextual keywords". Örneğin, bir özellik bildiriminde, " get " ve " set " tanımlayıcıları özel anlamlara (erişimciler) sahiptir.For example, within a property declaration, the "get" and "set" identifiers have special meaning (Accessors). Bu konumlarda veya dışında bir tanımlayıcıya get set izin verilmez, bu nedenle bu kullanım bu sözcüklerin tanımlayıcı olarak kullanımıyla çakışmaz.An identifier other than get or set is never permitted in these locations, so this use does not conflict with a use of these words as identifiers. Örneğin, var örtük olarak yazılan yerel değişken bildirimlerinde (yerel değişken bildirimleri) "" tanımlayıcısına sahip gibi, bir bağlamsal anahtar sözcük, belirtilen adlarla çakışabilir.In other cases, such as with the identifier "var" in implicitly typed local variable declarations (Local variable declarations), a contextual keyword can conflict with declared names. Bu gibi durumlarda, belirtilen ad tanımlayıcı anahtar sözcük olarak tanımlayıcı kullanılarak önceliklidir.In such cases, the declared name takes precedence over the use of the identifier as a contextual keyword.

Değişmez DeğerlerLiterals

Değişmez değer, bir değerin kaynak kodu gösterimidir.A literal is a source code representation of a value.

literal
    : boolean_literal
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | null_literal
    ;

Boole sabit değerleriBoolean literals

İki Boolean değişmez değer vardır: true ve false .There are two boolean literal values: true and false.

boolean_literal
    : 'true'
    | 'false'
    ;

Boolean_literal türü bool .The type of a boolean_literal is bool.

Tamsayı sabit değerleriInteger literals

Tamsayı sabit değerleri,, ve türlerinin değerlerini yazmak için kullanılır int uint long ulong .Integer literals are used to write values of types int, uint, long, and ulong. Tamsayı sabit değerlerinde iki olası biçim vardır: Decimal ve onaltılı.Integer literals have two possible forms: decimal and hexadecimal.

integer_literal
    : decimal_integer_literal
    | hexadecimal_integer_literal
    ;

decimal_integer_literal
    : decimal_digit+ integer_type_suffix?
    ;

decimal_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    ;

integer_type_suffix
    : 'U' | 'u' | 'L' | 'l' | 'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
    ;

hexadecimal_integer_literal
    : '0x' hex_digit+ integer_type_suffix?
    | '0X' hex_digit+ integer_type_suffix?
    ;

hex_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';

Bir tamsayı sabit değerinin türü aşağıdaki şekilde belirlenir:The type of an integer literal is determined as follows:

  • Değişmez değerin soneki yoksa, bu türlerin değeri temsil edilebilir: int , uint , long , ulong .If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
  • Sabit değer veya tarafından sonekli ise U u , değeri gösterilebileceği bu türlerin birincileriyle sahiptir: uint , ulong .If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.
  • Sabit değer veya tarafından sonekli ise L l , değeri gösterilebileceği bu türlerin birincileriyle sahiptir: long , ulong .If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong.
  • Sabit değer,,,,,, veya tarafından sonekli ise, UL Ul uL ul LU Lu lU lu türüdür ulong .If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.

Bir tamsayı değişmez değeri ile temsil edilen değer, tür aralığının dışındaysa ulong , bir derleme zamanı hatası oluşur.If the value represented by an integer literal is outside the range of the ulong type, a compile-time error occurs.

Stil olarak "" harfine "" L l long basamağıyla karışmak kolay olduğundan l "" yerine "" yerine "" kullanılması önerilir 1 .As a matter of style, it is suggested that "L" be used instead of "l" when writing literals of type long, since it is easy to confuse the letter "l" with the digit "1".

En küçük int ve long değerlerin ondalık tamsayı değişmez değer olarak yazılmasına izin vermek için aşağıdaki iki kural bulunur:To permit the smallest possible int and long values to be written as decimal integer literals, the following two rules exist:

  • 2147483648 (2 ^ 31) değerine sahip bir decimal_integer_literal ve tek başına eksi işleç belirtecinin (birli eksi işleci) hemen ardından belirteç olarak hiçbir integer_type_suffix belirdiğinde, sonuç int -2147483648 (-2 ^ 31) değerine sahip bir sabit değerdir.When a decimal_integer_literal with the value 2147483648 (2^31) and no integer_type_suffix appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type int with the value -2147483648 (-2^31). Diğer tüm durumlarda decimal_integer_literal böyle bir tür uint .In all other situations, such a decimal_integer_literal is of type uint.
  • 9223372036854775808 (2 ^ 63) değerine sahip bir decimal_integer_literal ve integer_type_suffix ya da integer_type_suffix L ya da l bir tekil eksi işleç belirtecinin (birli eksi işleci) hemen ardından belirteç olarak göründüğünde, sonuç long -9223372036854775808 değeriyle bir sabittir (-2 ^ 63).When a decimal_integer_literal with the value 9223372036854775808 (2^63) and no integer_type_suffix or the integer_type_suffix L or l appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type long with the value -9223372036854775808 (-2^63). Diğer tüm durumlarda decimal_integer_literal böyle bir tür ulong .In all other situations, such a decimal_integer_literal is of type ulong.

Gerçek sabit değerlerReal literals

Gerçek sabit değerler, ve türlerinin değerlerini yazmak için float kullanılır double decimal .Real literals are used to write values of types float, double, and decimal.

real_literal
    : decimal_digit+ '.' decimal_digit+ exponent_part? real_type_suffix?
    | '.' decimal_digit+ exponent_part? real_type_suffix?
    | decimal_digit+ exponent_part real_type_suffix?
    | decimal_digit+ real_type_suffix
    ;

exponent_part
    : 'e' sign? decimal_digit+
    | 'E' sign? decimal_digit+
    ;

sign
    : '+'
    | '-'
    ;

real_type_suffix
    : 'F' | 'f' | 'D' | 'd' | 'M' | 'm'
    ;

Real_type_suffix belirtilmemişse, gerçek değişmez değerin türü double .If no real_type_suffix is specified, the type of the real literal is double. Aksi halde gerçek tür soneki gerçek değişmez değerin türünü aşağıdaki gibi belirler:Otherwise, the real type suffix determines the type of the real literal, as follows:

  • FYa da türünde olan gerçek bir sabit değer f float .A real literal suffixed by F or f is of type float. Örneğin,,, 1f ve değişmez 1.5f değerleri 1e10f 123.456F Tüm türündedir float .For example, the literals 1f, 1.5f, 1e10f, and 123.456F are all of type float.
  • DYa da türünde olan gerçek bir sabit değer d double .A real literal suffixed by D or d is of type double. Örneğin,,, 1d ve değişmez 1.5d değerleri 1e10d 123.456D Tüm türündedir double .For example, the literals 1d, 1.5d, 1e10d, and 123.456D are all of type double.
  • MYa da türünde olan gerçek bir sabit değer m decimal .A real literal suffixed by M or m is of type decimal. Örneğin,,, 1m ve değişmez 1.5m değerleri 1e10m 123.456M Tüm türündedir decimal .For example, the literals 1m, 1.5m, 1e10m, and 123.456M are all of type decimal. Bu değişmez değer, decimal tam değer alınarak bir değere dönüştürülür ve gerekirse, banker 'in yuvarlanması (ondalık türü) kullanılarak en yakın gösterilebilir tablo değerine yuvarlanır.This literal is converted to a decimal value by taking the exact value, and, if necessary, rounding to the nearest representable value using banker's rounding (The decimal type). Değer yuvarlanmamışsa veya değer sıfır değilse (ikinci durumda, işaret ve ölçek 0 olacak şekilde), sabit değerde görünen herhangi bir ölçek korunur.Any scale apparent in the literal is preserved unless the value is rounded or the value is zero (in which latter case the sign and scale will be 0). Bu nedenle, değişmez değer, 2.900m işaret, 0 katsayı ve Ölçekle ondalık değerini oluşturacak şekilde ayrıştırılacaktır 2900 3 .Hence, the literal 2.900m will be parsed to form the decimal with sign 0, coefficient 2900, and scale 3.

Belirtilen sabit değer belirtilen türde temsil edilemez, derleme zamanı hatası oluşur.If the specified literal cannot be represented in the indicated type, a compile-time error occurs.

Veya türünde gerçek bir sabit değerin değeri, float double IEEE "en yakına yuvarla" modu kullanılarak belirlenir.The value of a real literal of type float or double is determined by using the IEEE "round to nearest" mode.

Gerçek bir sabit değerde, ondalık ayırıcıdan sonra her zaman ondalık basamakların gerekli olduğunu unutmayın.Note that in a real literal, decimal digits are always required after the decimal point. Örneğin, 1.3F gerçek bir değişmez değerdir ancak 1.F değildir.For example, 1.3F is a real literal but 1.F is not.

Karakter sabit değerleriCharacter literals

Bir karakter sabiti tek bir karakteri temsil eder ve genellikle içinde olduğu gibi tırnak içindeki bir karakterden oluşur 'a' .A character literal represents a single character, and usually consists of a character in quotes, as in 'a'.

Note: ANTLR dilbilgisi gösterimi aşağıdaki kafa karıştırıcı yapar!Note: The ANTLR grammar notation makes the following confusing! ANTLR 'de yazdığınızda, \' tek bir teklife göre gelir ' .In ANTLR, when you write \' it stands for a single quote '. Yazdığınızda, \\ tek bir ters eğik çizgi için temsil eder \ .And when you write \\ it stands for a single backslash \. Bu nedenle, bir karakter sabit değeri için ilk kural tek bir teklifle, ardından bir karakterle ve tek bir teklifle başladığı anlamına gelir.Therefore the first rule for a character literal means it starts with a single quote, then a character, then a single quote. Ve olası basit kaçış dizileri,,, \' , \" \\ \0 \a , \b , \f , \n , \r , \t , \v ,,,,,.And the eleven possible simple escape sequences are \', \", \\, \0, \a, \b, \f, \n, \r, \t, \v.

character_literal
    : '\'' character '\''
    ;

character
    : single_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_character
    : '<Any character except \' (U+0027), \\ (U+005C), and new_line_character>'
    ;

simple_escape_sequence
    : '\\\'' | '\\"' | '\\\\' | '\\0' | '\\a' | '\\b' | '\\f' | '\\n' | '\\r' | '\\t' | '\\v'
    ;

hexadecimal_escape_sequence
    : '\\x' hex_digit hex_digit? hex_digit? hex_digit?;

Bir karaktere ters eğik çizgi karakteri () izleyen bir karakter \ Şu karakterlerden biri olmalıdır: ' ,,, " \ 0 , a , b , f , n , r , t ,, u U x v ,,,,,,.A character that follows a backslash character (\) in a character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Aksi takdirde, bir derleme zamanı hatası oluşur.Otherwise, a compile-time error occurs.

Onaltılı kaçış sırası, "" öğesinden sonra onaltılık sayı tarafından oluşturulan değeri içeren tek bir Unicode karakteri temsil eder \x .A hexadecimal escape sequence represents a single Unicode character, with the value formed by the hexadecimal number following "\x".

Bir karakter sabiti ile temsil edilen değer değerinden büyükse U+FFFF , bir derleme zamanı hatası oluşur.If the value represented by a character literal is greater than U+FFFF, a compile-time error occurs.

Bir karakter sabit değerinde Unicode karakter kaçış sırası (Unicode karakter kaçış dizileri), aralığında olmalıdır U+0000 U+FFFF .A Unicode character escape sequence (Unicode character escape sequences) in a character literal must be in the range U+0000 to U+FFFF.

Basit bir kaçış dizisi, aşağıdaki tabloda açıklandığı gibi bir Unicode karakter kodlamasını temsil eder.A simple escape sequence represents a Unicode character encoding, as described in the table below.

Kaçış sırasıEscape sequence Karakter adıCharacter name Unicode kodlamaUnicode encoding
\' Tek tırnakSingle quote 0x0027
\" Çift tırnakDouble quote 0x0022
\\ SolaBackslash 0x005C
\0 NullNull 0x0000
\a UyarıAlert 0x0007
\b Geri Al tuşuBackspace 0x0008
\f Form akışıForm feed 0x000C
\n Yeni satırNew line 0x000A
\r Satır başıCarriage return 0x000D
\t Yatay sekmeHorizontal tab 0x0009
\v Dikey sekmeVertical tab 0x000B

Character_literal türü char .The type of a character_literal is char.

Dize değişmez değerleriString literals

C#, dize sabit değerlerinin iki biçimini destekler: normal dize sabit değerleri _ ve _ * tam dize sabit değerleri *.C# supports two forms of string literals: regular string literals _ and _verbatim string literals**.

Normal bir dize sabit değeri, içinde olduğu gibi çift tırnak içine alınmış sıfır veya daha fazla karakterden oluşur "hello" ve hem basit kaçış dizilerini ( \t Tab karakteri için gibi), onaltılı ve Unicode kaçış dizilerini içerebilir.A regular string literal consists of zero or more characters enclosed in double quotes, as in "hello", and may include both simple escape sequences (such as \t for the tab character), and hexadecimal and Unicode escape sequences.

Tam dize değişmez değeri @ , bir karakteri ve ardından çift tırnak karakteri, sıfır veya daha fazla karakter ve bir kapanış çift tırnak karakteriyle oluşur.A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. Basit bir örnek vardır @"hello" .A simple example is @"hello". Tam bir dize sabit değerinde, sınırlayıcılar arasındaki karakterler tam olarak yorumlanır ve tek özel durum quote_escape_sequence.In a verbatim string literal, the characters between the delimiters are interpreted verbatim, the only exception being a quote_escape_sequence. Özellikle, basit kaçış dizileri ve onaltılı ve Unicode kaçış dizileri, tam dize değişmez değerlerinde işlenmez.In particular, simple escape sequences, and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. Tam dize değişmez değeri birden çok satıra yayılabilir.A verbatim string literal may span multiple lines.

string_literal
    : regular_string_literal
    | verbatim_string_literal
    ;

regular_string_literal
    : '"' regular_string_literal_character* '"'
    ;

regular_string_literal_character
    : single_regular_string_literal_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_regular_string_literal_character
    : '<Any character except " (U+0022), \\ (U+005C), and new_line_character>'
    ;

verbatim_string_literal
    : '@"' verbatim_string_literal_character* '"'
    ;

verbatim_string_literal_character
    : single_verbatim_string_literal_character
    | quote_escape_sequence
    ;

single_verbatim_string_literal_character
    : '<any character except ">'
    ;

quote_escape_sequence
    : '""'
    ;

Bir regular_string_literal_character ters eğik çizgi karakteri () izleyen bir karakter \ Şu karakterlerden biri olmalıdır: ' ,,, " \ 0 , a , b , f , n , r , t ,, u U x v ,,,,,,,,,,.A character that follows a backslash character (\) in a regular_string_literal_character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Aksi takdirde, bir derleme zamanı hatası oluşur.Otherwise, a compile-time error occurs.

ÖrnekteThe example

string a = "hello, world";                   // hello, world
string b = @"hello, world";                  // hello, world

string c = "hello \t world";                 // hello      world
string d = @"hello \t world";                // hello \t world

string e = "Joe said \"Hello\" to me";       // Joe said "Hello" to me
string f = @"Joe said ""Hello"" to me";      // Joe said "Hello" to me

string g = "\\\\server\\share\\file.txt";    // \\server\share\file.txt
string h = @"\\server\share\file.txt";       // \\server\share\file.txt

string i = "one\r\ntwo\r\nthree";
string j = @"one
two
three";

çeşitli dize sabit değerlerini gösterir.shows a variety of string literals. Son dize değişmez değeri, j birden çok satıra yayılan, tam bir dize sabit değeri.The last string literal, j, is a verbatim string literal that spans multiple lines. Yeni satır karakterleri gibi boşluk da dahil olmak üzere tırnak işaretleri arasındaki karakterler tam olarak korunur.The characters between the quotation marks, including white space such as new line characters, are preserved verbatim.

Bir onaltılık kaçış sırası, dizi onaltılık basamağa sahip olabilir, dize sabiti "\x123" 123 onaltılık değeri olan tek bir karakter içerir.Since a hexadecimal escape sequence can have a variable number of hex digits, the string literal "\x123" contains a single character with hex value 123. Onaltılık değeri 12 ve ardından karakter 3 olan karakteri içeren bir dize oluşturmak için, bir tane yazabilir "\x00123" veya "\x12" + "3" bunun yerine.To create a string containing the character with hex value 12 followed by the character 3, one could write "\x00123" or "\x12" + "3" instead.

String_literaL türü string .The type of a string_literal is string.

Her dize sabit değeri, yeni bir dize örneği ile sonuçlanır.Each string literal does not necessarily result in a new string instance. Dize eşitlik işlecine (dize eşitlik işleçleri) göre eşdeğer olan iki veya daha fazla dize değişmez değeri aynı programda görünürse, bu dize değişmez değerleri aynı dize örneğine başvurur.When two or more string literals that are equivalent according to the string equality operator (String equality operators) appear in the same program, these string literals refer to the same string instance. Örneğin, tarafından oluşturulan çıkışFor instance, the output produced by

class Test
{
    static void Main() {
        object a = "hello";
        object b = "hello";
        System.Console.WriteLine(a == b);
    }
}

, True iki sabit değer aynı dize örneğine başvurduğundan.is True because the two literals refer to the same string instance.

Ara değerli dize sabit değerleriInterpolated string literals

Enterpolasyonlu dize sabit değerleri dize sabit değerlerine benzerdir, ancak { } deyimlerde olduğu gibi ve ile ayrılmış olan delikleri içerir.Interpolated string literals are similar to string literals, but contain holes delimited by { and }, wherein expressions can occur. Çalışma zamanında, ifadeler, metin biçimlerinin, delik oluşması durumunda dize üzerinde yer aldığı amaçla değerlendirilir.At runtime, the expressions are evaluated with the purpose of having their textual forms substituted into the string at the place where the hole occurs. Dize ilişkilendirtiğinin sözdizimi ve semantiği bölümünde açıklanmaktadır (enterpolasyonlu dizeler).The syntax and semantics of string interpolation are described in section (Interpolated strings).

Dize sabit değerleri gibi, enterpolasyonlu dize değişmez değerleri normal veya tam olabilir.Like string literals, interpolated string literals can be either regular or verbatim. Enterpolasyonlu normal dize sabit değerleri ve ile sınırlandırılır $" " ve enterpolasyonlu değişmez dize değerleri ve ile sınırlandırılmıştır $@" " .Interpolated regular string literals are delimited by $" and ", and interpolated verbatim string literals are delimited by $@" and ".

Diğer değişmez değerler gibi, bir enterpolasyonlu dize sabit değerinin sözcük analizi, aşağıdaki Dilbilgisine göre ilk olarak tek bir belirtece neden olur.Like other literals, lexical analysis of an interpolated string literal initially results in a single token, as per the grammar below. Ancak, sözdizimsel Analize göre, bir ara değer dizesinin tek belirteci, delikleri kapsayan dizenin bölümleri için birkaç belirtece bölünmüştür ve deliklere gerçekleşen giriş öğeleri, sözcüksel olarak analiz edilir.However, before syntactic analysis, the single token of an interpolated string literal is broken into several tokens for the parts of the string enclosing the holes, and the input elements occurring in the holes are lexically analysed again. Bu işlem, işlenmek üzere daha fazla enterpolasyonlu dize değişmezleri üretebilir. ancak, sözcüksel doğru olursa, sonunda sözdizimsel çözümlemenin işlemesi için bir dizi belirtece yol açacaktır.This may in turn produce more interpolated string literals to be processed, but, if lexically correct, will eventually lead to a sequence of tokens for syntactic analysis to process.

interpolated_string_literal
    : '$' interpolated_regular_string_literal
    | '$' interpolated_verbatim_string_literal
    ;

interpolated_regular_string_literal
    : interpolated_regular_string_whole
    | interpolated_regular_string_start  interpolated_regular_string_literal_body interpolated_regular_string_end
    ;

interpolated_regular_string_literal_body
    : regular_balanced_text
    | interpolated_regular_string_literal_body interpolated_regular_string_mid regular_balanced_text
    ;

interpolated_regular_string_whole
    : '"' interpolated_regular_string_character* '"'
    ;

interpolated_regular_string_start
    : '"' interpolated_regular_string_character* '{'
    ;

interpolated_regular_string_mid
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '{'
    ;

interpolated_regular_string_end
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '"'
    ;

interpolated_regular_string_characters_after_brace
    : interpolated_regular_string_character_no_brace
    | interpolated_regular_string_characters_after_brace interpolated_regular_string_character
    ;

interpolated_regular_string_character
    : single_interpolated_regular_string_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;

interpolated_regular_string_character_no_brace
    : '<Any interpolated_regular_string_character except close_brace_escape_sequence and any hexadecimal_escape_sequence or unicode_escape_sequence designating } (U+007D)>'
    ;

single_interpolated_regular_string_character
    : '<Any character except \" (U+0022), \\ (U+005C), { (U+007B), } (U+007D), and new_line_character>'
    ;

open_brace_escape_sequence
    : '{{'
    ;

close_brace_escape_sequence
    : '}}'
    ;
    
regular_balanced_text
    : regular_balanced_text_part+
    ;

regular_balanced_text_part
    : single_regular_balanced_text_character
    | delimited_comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' regular_balanced_text ')'
    | '[' regular_balanced_text ']'
    | '{' regular_balanced_text '}'
    ;
    
single_regular_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B), } (U+007D) and new_line_character>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;
    
interpolation_format
    : ':' interpolation_format_character+
    ;
    
interpolation_format_character
    : '<Any character except \" (U+0022), : (U+003A), { (U+007B) and } (U+007D)>'
    ;
    
interpolated_verbatim_string_literal
    : interpolated_verbatim_string_whole
    | interpolated_verbatim_string_start interpolated_verbatim_string_literal_body interpolated_verbatim_string_end
    ;

interpolated_verbatim_string_literal_body
    : verbatim_balanced_text
    | interpolated_verbatim_string_literal_body interpolated_verbatim_string_mid verbatim_balanced_text
    ;
    
interpolated_verbatim_string_whole
    : '@"' interpolated_verbatim_string_character* '"'
    ;
    
interpolated_verbatim_string_start
    : '@"' interpolated_verbatim_string_character* '{'
    ;
    
interpolated_verbatim_string_mid
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '{'
    ;
    
interpolated_verbatim_string_end
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '"'
    ;
    
interpolated_verbatim_string_characters_after_brace
    : interpolated_verbatim_string_character_no_brace
    | interpolated_verbatim_string_characters_after_brace interpolated_verbatim_string_character
    ;
    
interpolated_verbatim_string_character
    : single_interpolated_verbatim_string_character
    | quote_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;
    
interpolated_verbatim_string_character_no_brace
    : '<Any interpolated_verbatim_string_character except close_brace_escape_sequence>'
    ;
    
single_interpolated_verbatim_string_character
    : '<Any character except \" (U+0022), { (U+007B) and } (U+007D)>'
    ;
    
verbatim_balanced_text
    : verbatim_balanced_text_part+
    ;

verbatim_balanced_text_part
    : single_verbatim_balanced_text_character
    | comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' verbatim_balanced_text ')'
    | '[' verbatim_balanced_text ']'
    | '{' verbatim_balanced_text '}'
    ;
    
single_verbatim_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B) and } (U+007D)>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;

İnterpolated_string_literal belirteci, interpolated_string_literal oluşma sırasına göre aşağıdaki gibi birden fazla belirteç ve diğer giriş öğeleri olarak yeniden yorumlanır:An interpolated_string_literal token is reinterpreted as multiple tokens and other input elements as follows, in order of occurrence in the interpolated_string_literal:

  • Aşağıdakilerin oluşumları ayrı ayrı belirteçler olarak yeniden yorumlanır: önde gelen $ işareti, interpolated_regular_string_whole, interpolated_regular_string_start, interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_whole, interpolated_verbatim_string_start, interpolated_verbatim_string_mid ve interpolated_verbatim_string_end.Occurrences of the following are reinterpreted as separate individual tokens: the leading $ sign, interpolated_regular_string_whole, interpolated_regular_string_start, interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_whole, interpolated_verbatim_string_start, interpolated_verbatim_string_mid and interpolated_verbatim_string_end.
  • Bunlar arasında regular_balanced_text ve verbatim_balanced_text örnekleri input_section (sözcük temelli analiz) olarak yeniden işlenir ve giriş öğelerinin ortaya çıkan sırası olarak yeniden yorumlanır.Occurrences of regular_balanced_text and verbatim_balanced_text between these are reprocessed as an input_section (Lexical analysis) and are reinterpreted as the resulting sequence of input elements. Bunlar, yeniden yorumlanan enterpolasyonlu dize sabit belirteçlerini içerebilir.These may in turn include interpolated string literal tokens to be reinterpreted.

Sözdizimsel analiz, belirteçleri bir interpolated_string_expression (enterpolasyonlu dizeler) olarak yeniden birleştirir.Syntactic analysis will recombine the tokens into an interpolated_string_expression (Interpolated strings).

Örnek TODOExamples TODO

Null değişmez değeriThe null literal

null_literal
    : 'null'
    ;

Null_literal , örtülü olarak bir başvuru türüne veya null olabilir türe dönüştürülebilir.The null_literal can be implicitly converted to a reference type or nullable type.

İşleçler ve noktalama işaretleriOperators and punctuators

Birkaç tip işleç ve noktalama işareti vardır.There are several kinds of operators and punctuators. İşleçler, bir veya daha fazla işlenen içeren işlemleri betimleyen ifadelerde kullanılır.Operators are used in expressions to describe operations involving one or more operands. Örneğin a + b ifadesi, iki işleneni (a ve b) toplamak için + işlecini kullanır.For example, the expression a + b uses the + operator to add the two operands a and b. Noktalama işaretleri, gruplandırma ve ayırma için kullanılır.Punctuators are for grouping and separating.

operator_or_punctuator
    : '{'  | '}'  | '['  | ']'  | '('   | ')'  | '.'  | ','  | ':'  | ';'
    | '+'  | '-'  | '*'  | '/'  | '%'   | '&'  | '|'  | '^'  | '!'  | '~'
    | '='  | '<'  | '>'  | '?'  | '??'  | '::' | '++' | '--' | '&&' | '||'
    | '->' | '==' | '!=' | '<=' | '>='  | '+=' | '-=' | '*=' | '/=' | '%='
    | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>'
    ;

right_shift
    : '>>'
    ;

right_shift_assignment
    : '>>='
    ;

Right_shift ve right_shift_assignment üretimlerde dikey çubuk, söz dizimi arasındaki diğer üretimlerin aksine, belirteçler arasında herhangi bir türde (hatta boşluk değil) bir karakter olmasına izin verileceğini belirtmek için kullanılır.The vertical bar in the right_shift and right_shift_assignment productions are used to indicate that, unlike other productions in the syntactic grammar, no characters of any kind (not even whitespace) are allowed between the tokens. Bu üretimler, type_parameter_list s (tür parametrelerinin) doğru işlemesini etkinleştirmek için özel olarak değerlendirilir.These productions are treated specially in order to enable the correct handling of type_parameter_list s (Type parameters).

Ön işleme yönergeleriPre-processing directives

Ön işleme yönergeleri, kaynak dosyalarının bölümlerini koşullu olarak atlama, hata ve uyarı koşullarını raporlama ve kaynak kodunun farklı bölgelerini ayırıcı yapma yeteneği sağlar.The pre-processing directives provide the ability to conditionally skip sections of source files, to report error and warning conditions, and to delineate distinct regions of source code. "Ön işleme yönergeleri" terimi yalnızca C ve C++ programlama dilleri ile tutarlılık için kullanılır.The term "pre-processing directives" is used only for consistency with the C and C++ programming languages. C# ' de, ayrı bir ön işleme adımı yoktur; ön işleme yönergeleri, sözcük temelli analiz aşamasının bir parçası olarak işlenir.In C#, there is no separate pre-processing step; pre-processing directives are processed as part of the lexical analysis phase.

pp_directive
    : pp_declaration
    | pp_conditional
    | pp_line
    | pp_diagnostic
    | pp_region
    | pp_pragma
    ;

Aşağıdaki ön işleme yönergeleri mevcuttur:The following pre-processing directives are available:

  • #define ve #undef sırasıyla, koşullu derleme sembollerini (bildirim yönergeleri) tanımlamak ve bunları kaldırmak için kullanılır.#define and #undef, which are used to define and undefine, respectively, conditional compilation symbols (Declaration directives).
  • #if, #elif , #else ve #endif , kaynak kodu bölümlerini koşullu olarak atlamak Için kullanılır (koşullu derleme yönergeleri).#if, #elif, #else, and #endif, which are used to conditionally skip sections of source code (Conditional compilation directives).
  • #line, hatalar ve uyarılar için oluşturulan satır numaralarını denetlemek için kullanılan (satır yönergeleri).#line, which is used to control line numbers emitted for errors and warnings (Line directives).
  • #error ve #warning sırasıyla hata ve uyarı vermek için kullanılır (tanı yönergeleri).#error and #warning, which are used to issue errors and warnings, respectively (Diagnostic directives).
  • #region``#endregionkaynak kodun (bölge yönergeleri) bölümlerini açıkça işaretlemek için de kullanılır.#region and #endregion, which are used to explicitly mark sections of source code (Region directives).
  • #pragmaderleyici için isteğe bağlı bağlamsal bilgileri belirtmek için kullanılan (pragma yönergeleri).#pragma, which is used to specify optional contextual information to the compiler (Pragma directives).

Bir ön işleme yönergesi her zaman ayrı bir kaynak kod satırı kaplar ve her zaman bir # karakter ve bir ön işleme yönergesi adıyla başlar.A pre-processing directive always occupies a separate line of source code and always begins with a # character and a pre-processing directive name. Karakterden önce boşluk, karakter # # ve yönerge adı arasında boşluk oluşabilir.White space may occur before the # character and between the # character and the directive name.

,,,,, #define ,, Veya yönergesini içeren bir kaynak satırı, #undef #if #elif #else #endif #line #endregion tek satırlık bir açıklama ile sona başlayabilir.A source line containing a #define, #undef, #if, #elif, #else, #endif, #line, or #endregion directive may end with a single-line comment. /* */Önceden işleme yönergelerini içeren kaynak satırlarda sınırlandırılmış açıklamalara (yorumların stili) izin verilmez.Delimited comments (the /* */ style of comments) are not permitted on source lines containing pre-processing directives.

Ön işleme yönergeleri belirteç değildir ve C# ' nin sözdizimsel dilbilgisinde bir parçası değildir.Pre-processing directives are not tokens and are not part of the syntactic grammar of C#. Ancak, önceden işleme yönergeleri, belirteç dizilerini dahil etmek veya hariç tutmak için kullanılabilir ve bu şekilde bir C# programının anlamını etkileyebilir.However, pre-processing directives can be used to include or exclude sequences of tokens and can in that way affect the meaning of a C# program. Örneğin, derlendiğinde program:For example, when compiled, the program:

#define A
#undef B

class C
{
#if A
    void F() {}
#else
    void G() {}
#endif

#if B
    void H() {}
#else
    void I() {}
#endif
}

program ile aynı belirteçlerin tam dizisiyle sonuçlanır:results in the exact same sequence of tokens as the program:

class C
{
    void F() {}
    void I() {}
}

Bu nedenle, sözcüksel olarak iki program çok farklı, sözdizimsel olarak aynıdır.Thus, whereas lexically, the two programs are quite different, syntactically, they are identical.

Koşullu derleme sembolleriConditional compilation symbols

,, Ve yönergeleri tarafından sunulan koşullu derleme işlevselliği, #if #elif #else #endif ön işleme ifadeleri (ön işleme ifadeleri) ve koşullu derleme sembolleri aracılığıyla denetlenir.The conditional compilation functionality provided by the #if, #elif, #else, and #endif directives is controlled through pre-processing expressions (Pre-processing expressions) and conditional compilation symbols.

conditional_symbol
    : '<Any identifier_or_keyword except true or false>'
    ;

Koşullu derleme sembolünün iki olası durumu vardır: *tanımlı _ veya _ tanımsız *.A conditional compilation symbol has two possible states: defined _ or _undefined**. Bir kaynak dosyanın sözcük işleme başlangıcında, bir dış mekanizma (bir komut satırı derleyici seçeneği gibi) tarafından açıkça tanımlanmadığı sürece koşullu derleme simgesi tanımsızdır.At the beginning of the lexical processing of a source file, a conditional compilation symbol is undefined unless it has been explicitly defined by an external mechanism (such as a command-line compiler option). Bir #define yönerge işlendiğinde, Bu yönergede adlı koşullu derleme sembolü bu kaynak dosyada tanımlanır.When a #define directive is processed, the conditional compilation symbol named in that directive becomes defined in that source file. Sembol, #undef aynı simgenin bir yönergesi işlenene veya kaynak dosyanın sonuna ulaşılana kadar tanımlanmış olarak kalır.The symbol remains defined until an #undef directive for that same symbol is processed, or until the end of the source file is reached. Bunun bir #define #undef etkisi, bir kaynak dosyasındaki yönergelerin aynı programdaki diğer kaynak dosyaları üzerinde hiçbir etkisi olmaması.An implication of this is that #define and #undef directives in one source file have no effect on other source files in the same program.

Bir ön işleme ifadesinde başvurulmadığında, tanımlı bir koşullu derleme sembolünün Boole değeri vardır true ve tanımsız bir koşullu derleme sembolü Boolean değerine sahiptir false .When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false. Koşullu derleme simgelerinin, ön işleme ifadelerinde başvurulmadan önce açıkça bildirilmesini gerektiren bir gereksinim yoktur.There is no requirement that conditional compilation symbols be explicitly declared before they are referenced in pre-processing expressions. Bunun yerine, bildirilmemiş semboller yalnızca tanımsız olur ve bu nedenle değeri vardır false .Instead, undeclared symbols are simply undefined and thus have the value false.

Koşullu derleme sembolleri için ad alanı, C# programındaki diğer tüm adlandırılmış varlıklardan farklıdır ve ayrıdır.The name space for conditional compilation symbols is distinct and separate from all other named entities in a C# program. Koşullu derleme sembollerine yalnızca #define ve #undef yönergeleriyle ve önceden işleme ifadelerinde başvurulabilir.Conditional compilation symbols can only be referenced in #define and #undef directives and in pre-processing expressions.

Ön işleme ifadeleriPre-processing expressions

Ön işleme ifadeleri, #if ve yönergeleri içinde oluşabilir #elif .Pre-processing expressions can occur in #if and #elif directives. ,, ! Ve işleçlerine == != && || ön işleme ifadelerinde izin verilir ve gruplama için parantezler kullanılabilir.The operators !, ==, !=, && and || are permitted in pre-processing expressions, and parentheses may be used for grouping.

pp_expression
    : whitespace? pp_or_expression whitespace?
    ;

pp_or_expression
    : pp_and_expression
    | pp_or_expression whitespace? '||' whitespace? pp_and_expression
    ;

pp_and_expression
    : pp_equality_expression
    | pp_and_expression whitespace? '&&' whitespace? pp_equality_expression
    ;

pp_equality_expression
    : pp_unary_expression
    | pp_equality_expression whitespace? '==' whitespace? pp_unary_expression
    | pp_equality_expression whitespace? '!=' whitespace? pp_unary_expression
    ;

pp_unary_expression
    : pp_primary_expression
    | '!' whitespace? pp_unary_expression
    ;

pp_primary_expression
    : 'true'
    | 'false'
    | conditional_symbol
    | '(' whitespace? pp_expression whitespace? ')'
    ;

Bir ön işleme ifadesinde başvurulmadığında, tanımlı bir koşullu derleme sembolünün Boole değeri vardır true ve tanımsız bir koşullu derleme sembolü Boolean değerine sahiptir false .When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false.

Bir ön işleme ifadesinin değerlendirmesi her zaman bir Boole değeri verir.Evaluation of a pre-processing expression always yields a boolean value. Bir ön işleme ifadesi için değerlendirme kuralları bir sabit ifade (sabit ifadeler) ile aynıdır, ancak başvurılabilen Kullanıcı tanımlı varlıkların koşullu derleme sembolleri vardır.The rules of evaluation for a pre-processing expression are the same as those for a constant expression (Constant expressions), except that the only user-defined entities that can be referenced are conditional compilation symbols.

Bildirim yönergeleriDeclaration directives

Bildirim yönergeleri, koşullu derleme sembollerini tanımlamak veya tanımlamak için kullanılır.The declaration directives are used to define or undefine conditional compilation symbols.

pp_declaration
    : whitespace? '#' whitespace? 'define' whitespace conditional_symbol pp_new_line
    | whitespace? '#' whitespace? 'undef' whitespace conditional_symbol pp_new_line
    ;

pp_new_line
    : whitespace? single_line_comment? new_line
    ;

Bir yönergeyi işleme, #define belirtilen koşullu derleme sembolünün, yönergeyi izleyen kaynak satırla başlayarak tanımlanmasını sağlar.The processing of a #define directive causes the given conditional compilation symbol to become defined, starting with the source line that follows the directive. Benzer şekilde, bir yönergenin işlenmesi #undef verilen koşullu derleme sembolünün, yönergeyi izleyen kaynak satırla başlayarak tanımsız hale gelmesine neden olur.Likewise, the processing of an #undef directive causes the given conditional compilation symbol to become undefined, starting with the source line that follows the directive.

Kaynak dosyadaki tüm #define ve #undef yönergelerinin kaynak dosyadaki ilk belirteçten (belirteçler) önce gerçekleşmesi gerekir; Aksi takdirde derleme zamanı hatası oluşur.Any #define and #undef directives in a source file must occur before the first token (Tokens) in the source file; otherwise a compile-time error occurs. Sezgisel koşullarda #define ve #undef yönergeler kaynak dosyadaki tüm "gerçek koddan" gelmelidir.In intuitive terms, #define and #undef directives must precede any "real code" in the source file.

Örnek:The example:

#define Enterprise

#if Professional || Enterprise
    #define Advanced
#endif

namespace Megacorp.Data
{
    #if Advanced
    class PivotTable {...}
    #endif
}

, #define kaynak dosyadaki ilk belirteçten (anahtar sözcüğü) önce gelen yönergeler için geçerlidir namespace .is valid because the #define directives precede the first token (the namespace keyword) in the source file.

Aşağıdaki örnek, bir derleme zamanı hatasına neden olur çünkü bu, #define gerçek bir kod izler:The following example results in a compile-time error because a #define follows real code:

#define A
namespace N
{
    #define B
    #if B
    class Class1 {}
    #endif
}

#define, Zaten tanımlanmış olan bir koşullu derleme sembolünü tanımlayabilir, bu sembol için herhangi bir araya girmeden #undef emin olamaz.A #define may define a conditional compilation symbol that is already defined, without there being any intervening #undef for that symbol. Aşağıdaki örnek bir koşullu derleme sembolünü tanımlar A ve sonra yeniden tanımlar.The example below defines a conditional compilation symbol A and then defines it again.

#define A
#define A

#undefTanımlı olmayan bir koşullu derleme sembolünü "tanımlayabilir".A #undef may "undefine" a conditional compilation symbol that is not defined. Aşağıdaki örnek bir koşullu derleme sembolünü tanımlar A ve iki kez tanımlamaz; ikincisi #undef hiçbir etkiye sahip olmasa da, hala geçerli olur.The example below defines a conditional compilation symbol A and then undefines it twice; although the second #undef has no effect, it is still valid.

#define A
#undef A
#undef A

Koşullu derleme yönergeleriConditional compilation directives

Koşullu derleme yönergeleri, kaynak dosyanın bölümlerini koşullu olarak dahil etmek veya hariç tutmak için kullanılır.The conditional compilation directives are used to conditionally include or exclude portions of a source file.

pp_conditional
    : pp_if_section pp_elif_section* pp_else_section? pp_endif
    ;

pp_if_section
    : whitespace? '#' whitespace? 'if' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_elif_section
    : whitespace? '#' whitespace? 'elif' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_else_section:
    | whitespace? '#' whitespace? 'else' pp_new_line conditional_section?
    ;

pp_endif
    : whitespace? '#' whitespace? 'endif' pp_new_line
    ;

conditional_section
    : input_section
    | skipped_section
    ;

skipped_section
    : skipped_section_part+
    ;

skipped_section_part
    : skipped_characters? new_line
    | pp_directive
    ;

skipped_characters
    : whitespace? not_number_sign input_character*
    ;

not_number_sign
    : '<Any input_character except #>'
    ;

Sözdizimi tarafından gösterildiği gibi, koşullu derleme yönergeleri, sırasıyla, bir #if yönerge, sıfır veya daha fazla yönerge, #elif sıfır veya bir #else yönerge ve bir yönerge olarak yazılmış şekilde yazılmalıdır #endif .As indicated by the syntax, conditional compilation directives must be written as sets consisting of, in order, an #if directive, zero or more #elif directives, zero or one #else directive, and an #endif directive. Yönergeler arasında kaynak kodunun koşullu bölümleri bulunur.Between the directives are conditional sections of source code. Her bölüm hemen önceki yönerge tarafından denetlenir.Each section is controlled by the immediately preceding directive. Koşullu bir bölümün kendisi bu yönergeler için tüm kümeler için iç içe geçmiş koşullu derleme yönergeleri içerebilir.A conditional section may itself contain nested conditional compilation directives provided these directives form complete sets.

Pp_conditional normal sözcük işleme için kapsanan conditional_section s 'nin en çok birini seçer:A pp_conditional selects at most one of the contained conditional_section s for normal lexical processing:

  • Ve yönergelerinin pp_expression, #if #elif bir alınana kadar sırayla değerlendirilir true .The pp_expression s of the #if and #elif directives are evaluated in order until one yields true. Bir ifade varsa true , karşılık gelen yönergenin conditional_section seçilir.If an expression yields true, the conditional_section of the corresponding directive is selected.
  • Tüm pp_expression yield false ve bir #else yönerge varsa, yönergesinin conditional_section #else seçilir.If all pp_expression s yield false, and if an #else directive is present, the conditional_section of the #else directive is selected.
  • Aksi takdirde, conditional_section seçili değildir.Otherwise, no conditional_section is selected.

Seçilen conditional_section, varsa normal input_section olarak işlenir: bölümünde yer alan kaynak kodu, sözlü dilbilgisine uymalıdır; belirteçler, bölümündeki kaynak koddan oluşturulur; ve bölümündeki ön işleme yönergelerinin tanımlanmış etkileri vardır.The selected conditional_section, if any, is processed as a normal input_section: the source code contained in the section must adhere to the lexical grammar; tokens are generated from the source code in the section; and pre-processing directives in the section have the prescribed effects.

Kalan conditional_section s, varsa, skipped_section s olarak işlenir: ön işleme yönergeleri haricinde, bölümdeki kaynak kodunun sözlü dilbilgisine bağlı olmaması gerekir; bölümünde kaynak koddan hiçbir belirteç oluşturulmaz; ve bölümündeki ön işleme yönergeleri, sözcüksel doğru olmalıdır ancak başka türlü işlenmemelidir.The remaining conditional_section s, if any, are processed as skipped_section s: except for pre-processing directives, the source code in the section need not adhere to the lexical grammar; no tokens are generated from the source code in the section; and pre-processing directives in the section must be lexically correct but are not otherwise processed. Skipped_section olarak işlenmekte olan bir conditional_section içinde, iç içe geçmiş conditional_section(iç içe geçmiş #if ... #endif ve #region ... #endregion yapılar) da skipped_section s olarak işlenir.Within a conditional_section that is being processed as a skipped_section, any nested conditional_section s (contained in nested #if...#endif and #region...#endregion constructs) are also processed as skipped_section s.

Aşağıdaki örnek, koşullu derleme yönergelerinin nasıl iç içe geçirebileceği gösterilmektedir:The following example illustrates how conditional compilation directives can nest:

#define Debug       // Debugging on
#undef Trace        // Tracing off

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
            #if Trace
                WriteToLog(this.ToString());
            #endif
        #endif
        CommitHelper();
    }
}

Ön işleme yönergeleri hariç, atlanan kaynak kodu sözcük temelli analize tabi değildir.Except for pre-processing directives, skipped source code is not subject to lexical analysis. Örneğin, aşağıdaki, bölümünde Sonlandırılmamış açıklamaya rağmen geçerlidir #else :For example, the following is valid despite the unterminated comment in the #else section:

#define Debug        // Debugging on

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
        #else
            /* Do something else
        #endif
    }
}

Ancak, bu ön işleme yönergelerinin kaynak kodun atlanan bölümlerinde bile, sözcüksel olarak doğru olması gerektiğini unutmayın.Note, however, that pre-processing directives are required to be lexically correct even in skipped sections of source code.

Önceden işleme yönergeleri, çok satırlı giriş öğeleri içinde göründükleri zaman işlenmez.Pre-processing directives are not processed when they appear inside multi-line input elements. Örneğin, program:For example, the program:

class Hello
{
    static void Main() {
        System.Console.WriteLine(@"hello, 
#if Debug
        world
#else
        Nebraska
#endif
        ");
    }
}

çıkışın sonucu:results in the output:

hello,
#if Debug
        world
#else
        Nebraska
#endif

Bu durumlarda, işlenen önceden işleme yönergelerinin kümesi, pp_expression değerlendirmesine bağlı olarak değişebilir.In peculiar cases, the set of pre-processing directives that is processed might depend on the evaluation of the pp_expression. Örnek:The example:

#if X
    /*
#else
    /* */ class Q { }
#endif

class Q { } , X tanımlanmadığına bakılmaksızın her zaman aynı belirteç akışını () üretir.always produces the same token stream (class Q { }), regardless of whether or not X is defined. XTanımlı ise, #if #endif çok satırlı yorum nedeniyle işlenen tek yönergeler ve olur.If X is defined, the only processed directives are #if and #endif, due to the multi-line comment. XTanımlanmamışsa, üç yönerge ( #if , #else , #endif ) yönerge kümesinin bir parçasıdır.If X is undefined, then three directives (#if, #else, #endif) are part of the directive set.

Tanılama yönergeleriDiagnostic directives

Tanılama yönergeleri, diğer derleme zamanı hatalarıyla ve uyarılarla aynı şekilde bildirilen hata ve uyarı iletilerini açık bir şekilde oluşturmak için kullanılır.The diagnostic directives are used to explicitly generate error and warning messages that are reported in the same way as other compile-time errors and warnings.

pp_diagnostic
    : whitespace? '#' whitespace? 'error' pp_message
    | whitespace? '#' whitespace? 'warning' pp_message
    ;

pp_message
    : new_line
    | whitespace input_character* new_line
    ;

Örnek:The example:

#warning Code review needed before check-in

#if Debug && Retail
    #error A build can't be both debug and retail
#endif

class Test {...}

her zaman bir uyarı üretir ("iade etmeden önce kod incelemesi gereklidir") ve koşullu semboller Debug ve ikisi de tanımlanmışsa bir derleme zamanı hatası ("derleme hem hata ayıklama hem de perakende olamaz") oluşturur Retail .always produces a warning ("Code review needed before check-in"), and produces a compile-time error ("A build can't be both debug and retail") if the conditional symbols Debug and Retail are both defined. Pp_message , rastgele metin içerebileceğini unutmayın; Özellikle, sözcükteki tek tırnak içinde gösterildiği gibi iyi biçimlendirilmiş belirteçler içermesi gerekmez can't .Note that a pp_message can contain arbitrary text; specifically, it need not contain well-formed tokens, as shown by the single quote in the word can't.

Bölge yönergeleriRegion directives

Bölge yönergeleri, kaynak kodu bölgelerini açıkça işaretlemek için kullanılır.The region directives are used to explicitly mark regions of source code.

pp_region
    : pp_start_region conditional_section? pp_end_region
    ;

pp_start_region
    : whitespace? '#' whitespace? 'region' pp_message
    ;

pp_end_region
    : whitespace? '#' whitespace? 'endregion' pp_message
    ;

Bir bölgeye hiçbir anlam anlamı eklenmez; bölgeler, programcı tarafından veya kaynak kodun bir bölümünü işaretlemek için otomatikleştirilmiş araçlar tarafından kullanılmak üzere tasarlanmıştır.No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. #regionAynı şekilde veya yönergesinde belirtilen iletide #endregion anlam anlamı yoktur; yalnızca bölgeyi tanımlamak için kullanılır.The message specified in a #region or #endregion directive likewise has no semantic meaning; it merely serves to identify the region. Eşleştirme #region ve #endregion yönergeler farklı pp_message s olabilir.Matching #region and #endregion directives may have different pp_message s.

Bir bölgenin sözcük işleme işlemi:The lexical processing of a region:

#region
...
#endregion

formun koşullu bir derleme yönergesinin yalnızca sözcük işleme öğesine karşılık gelir:corresponds exactly to the lexical processing of a conditional compilation directive of the form:

#if true
...
#endif

Çizgi yönergeleriLine directives

Satır yönergeleri, uyarı ve hatalar gibi, derleyici tarafından raporlanan ve arayan bilgi öznitelikleri (çağıran bilgi öznitelikleri) tarafından kullanılan satır numaralarını ve kaynak dosya adlarını değiştirmek için kullanılabilir.Line directives may be used to alter the line numbers and source file names that are reported by the compiler in output such as warnings and errors, and that are used by caller info attributes (Caller info attributes).

Satır yönergeleri en yaygın olarak, diğer bir metin girişinden C# kaynak kodu üreten meta programlama araçlarında kullanılır.Line directives are most commonly used in meta-programming tools that generate C# source code from some other text input.

pp_line
    : whitespace? '#' whitespace? 'line' whitespace line_indicator pp_new_line
    ;

line_indicator
    : decimal_digit+ whitespace file_name
    | decimal_digit+
    | 'default'
    | 'hidden'
    ;

file_name
    : '"' file_name_character+ '"'
    ;

file_name_character
    : '<Any input_character except ">'
    ;

Hiçbir #line yönergesi yoksa, derleyici çıktıda gerçek satır numaralarını ve kaynak dosya adlarını raporlar.When no #line directives are present, the compiler reports true line numbers and source file names in its output. #lineOlmayan bir line_indicator içeren bir yönergeyi işlerken, derleyici, belirtilen default satır numarası (ve belirtilmişse dosya adı) gibi yönergeden sonra satırı değerlendirir.When processing a #line directive that includes a line_indicator that is not default, the compiler treats the line after the directive as having the given line number (and file name, if specified).

Bir #line default yönerge, önceki tüm #line yönergelerinin etkisini tersine çevirir.A #line default directive reverses the effect of all preceding #line directives. Derleyici, kesin olmayan bir yönergeler gibi, izleyen satırlar için gerçek satır bilgilerini raporlar #line .The compiler reports true line information for subsequent lines, precisely as if no #line directives had been processed.

Bir #line hidden yönergenin hata iletilerinde bildirilen dosya ve satır numaraları üzerinde hiçbir etkisi yoktur, ancak kaynak düzeyinde hata ayıklamayı etkiler.A #line hidden directive has no effect on the file and line numbers reported in error messages, but does affect source level debugging. Hata ayıklarken, bir #line hidden yönergeyle sonraki yönerge (olmayan) arasındaki tüm satırlarda #line #line hidden satır numarası bilgisi yoktur.When debugging, all lines between a #line hidden directive and the subsequent #line directive (that is not #line hidden) have no line number information. Hata ayıklayıcıda kod üzerinden adımla, bu satırlar tamamen atlanır.When stepping through code in the debugger, these lines will be skipped entirely.

File_name , kaçış karakterlerinin işlenmediği normal bir dize sabit değerinden farklı olduğunu unutmayın; " \ " karakteri, file_name içinde normal ters eğik çizgi karakterini belirtir.Note that a file_name differs from a regular string literal in that escape characters are not processed; the "\" character simply designates an ordinary backslash character within a file_name.

Pragma yönergeleriPragma directives

#pragmaÖn işleme yönergesi, isteğe bağlı bağlamsal bilgileri derleyiciye belirtmek için kullanılır.The #pragma preprocessing directive is used to specify optional contextual information to the compiler. Bir yönergede sağlanan bilgiler #pragma hiçbir şekilde program semantiğini değiştirmez.The information supplied in a #pragma directive will never change program semantics.

pp_pragma
    : whitespace? '#' whitespace? 'pragma' whitespace pragma_body pp_new_line
    ;

pragma_body
    : pragma_warning_body
    ;

C#, #pragma derleyici uyarılarını denetlemek için yönergeler sağlar.C# provides #pragma directives to control compiler warnings. Dilin gelecekteki sürümleri ek #pragma yönergeler içerebilir.Future versions of the language may include additional #pragma directives. Diğer C# derleyicileri ile birlikte çalışabilirliği sağlamak için, Microsoft C# derleyicisi bilinmeyen yönergeler için derleme hataları vermez #pragma ; Bu yönergeler, ancak uyarılar oluşturur.To ensure interoperability with other C# compilers, the Microsoft C# compiler does not issue compilation errors for unknown #pragma directives; such directives do however generate warnings.

Pragma uyarısıPragma warning

#pragma warningYönerge, sonraki program metninin derlenmesi sırasında tüm veya belirli bir uyarı iletisi kümesini devre dışı bırakmak veya geri yüklemek için kullanılır.The #pragma warning directive is used to disable or restore all or a particular set of warning messages during compilation of the subsequent program text.

pragma_warning_body
    : 'warning' whitespace warning_action
    | 'warning' whitespace warning_action whitespace warning_list
    ;

warning_action
    : 'disable'
    | 'restore'
    ;

warning_list
    : decimal_digit+ (whitespace? ',' whitespace? decimal_digit+)*
    ;

#pragma warningUyarı listesini atlayacak bir yönerge tüm uyarıları etkiler.A #pragma warning directive that omits the warning list affects all warnings. #pragma warningUyarı listesi içeren bir yönerge yalnızca listede belirtilen uyarıları etkiler.A #pragma warning directive that includes a warning list affects only those warnings that are specified in the list.

Bir #pragma warning disable yönerge, tüm veya verilen uyarı kümesini devre dışı bırakır.A #pragma warning disable directive disables all or the given set of warnings.

Bir #pragma warning restore yönerge, derleme biriminin başlangıcında geçerli olan durum kümesini veya verilen uyarıları geri yükler.A #pragma warning restore directive restores all or the given set of warnings to the state that was in effect at the beginning of the compilation unit. Belirli bir uyarı dışarıdan devre dışı bırakılmışsa, bir #pragma warning restore (tümü veya belirli bir uyarı için) bu uyarıyı yeniden etkinleştiremeyeceğini unutmayın.Note that if a particular warning was disabled externally, a #pragma warning restore (whether for all or the specific warning) will not re-enable that warning.

Aşağıdaki örnek, kullanımdan çıkarıldığı #pragma warning zaman, Microsoft C# derleyicisinden alınan uyarı numarası kullanılarak, kullanım dışı bırakılmış üyelere başvuruluyorsa bildirilen uyarıyı geçici olarak devre dışı bırakmak için kullanımını gösterir.The following example shows use of #pragma warning to temporarily disable the warning reported when obsoleted members are referenced, using the warning number from the Microsoft C# compiler.

using System;

class Program
{
    [Obsolete]
    static void Foo() {}

    static void Main() {
#pragma warning disable 612
    Foo();
#pragma warning restore 612
    }
}