İfadelerExpressions

İfade, işleç ve işlenen dizisidir.An expression is a sequence of operators and operands. Bu bölümde sözdizimi, işlenenler ve işleçler değerlendirmesi sırası ve ifadelerin anlamı tanımlanmaktadır.This chapter defines the syntax, order of evaluation of operands and operators, and meaning of expressions.

İfade sınıflandırmalarıExpression classifications

Bir ifade, aşağıdakilerden biri olarak sınıflandırıldı:An expression is classified as one of the following:

  • Bir değer.A value. Her değerin ilişkili bir türü vardır.Every value has an associated type.
  • Bir değişken.A variable. Her değişkenin bir ilişkili türü vardır, yani bu değişkenin belirtilen türü.Every variable has an associated type, namely the declared type of the variable.
  • Ad alanı.A namespace. Bu sınıflandırmayla bir ifade, yalnızca bir member_access (üye erişimi) sol tarafında görünür.An expression with this classification can only appear as the left hand side of a member_access (Member access). Diğer bir bağlamda, ad alanı olarak sınıflandırılan bir ifade, derleme zamanı hatasına neden olur.In any other context, an expression classified as a namespace causes a compile-time error.
  • Bir tür.A type. Bu sınıflandırmayla bir ifade, yalnızca bir member_access (üye erişimi) veya as işleç (as işleci), is işleç (IS işleci) veya typeof işleç (typeof işleci) için bir işlenen olarak yalnızca sol tarafta görünebilir.An expression with this classification can only appear as the left hand side of a member_access (Member access), or as an operand for the as operator (The as operator), the is operator (The is operator), or the typeof operator (The typeof operator). Başka bir bağlamda, tür olarak sınıflandırılan bir ifade, derleme zamanı hatasına neden olur.In any other context, an expression classified as a type causes a compile-time error.
  • Bir üye aramasının (üye arama) sonucu olan aşırı yüklenmiş yöntemler kümesi olan bir yöntem grubu.A method group, which is a set of overloaded methods resulting from a member lookup (Member lookup). Bir yöntem grubunun ilişkili bir örnek ifadesi ve ilişkili bir tür bağımsız değişkeni listesi olabilir.A method group may have an associated instance expression and an associated type argument list. Bir örnek yöntemi çağrıldığında, örnek ifadesinin değerlendirilme sonucu tarafından temsil edilen örnek olur this (Bu erişim).When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access). Bir yöntem grubuna bir invocation_expression (çağırma ifadelerinde), bir delegate_creation_expression (temsilci oluşturma ifadeleri) ve bir bir bir işleç işlecinin sol tarafı olarak izin verilir ve örtülü olarak uyumlu bir temsilci türüne dönüştürülebilir (Yöntem grubu dönüştürmeleri).A method group is permitted in an invocation_expression (Invocation expressions) , a delegate_creation_expression (Delegate creation expressions) and as the left hand side of an is operator, and can be implicitly converted to a compatible delegate type (Method group conversions). Diğer bir bağlamda, Yöntem grubu olarak sınıflandırılan bir ifade derleme zamanı hatasına neden olur.In any other context, an expression classified as a method group causes a compile-time error.
  • Null bir sabit değer.A null literal. Bu sınıflandırmayla bir ifade, örtük olarak bir başvuru türüne veya null yapılabilir türe dönüştürülebilir.An expression with this classification can be implicitly converted to a reference type or nullable type.
  • Anonim bir işlev.An anonymous function. Bu sınıflandırmayla bir ifade, örtülü olarak uyumlu bir temsilci türüne veya ifade ağacı türüne dönüştürülebilir.An expression with this classification can be implicitly converted to a compatible delegate type or expression tree type.
  • Özellik erişimi.A property access. Her özellik erişiminin, özelliğin türü olarak ilişkili bir türü vardır.Every property access has an associated type, namely the type of the property. Ayrıca, özellik erişiminin ilişkili bir örnek ifadesi olabilir.Furthermore, a property access may have an associated instance expression. getÖrnek özellik erişiminin bir erişimcisi (veya set bloğu) çağrıldığında, örnek ifadesinin değerlendirilme sonucu tarafından temsil edilen örnek olur this (Bu erişim).When an accessor (the get or set block) of an instance property access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access).
  • Bir olay erişimi.An event access. Her olay erişiminde ilişkili bir tür bulunur, bu olay türü olayın türüdür.Every event access has an associated type, namely the type of the event. Ayrıca, bir olay erişiminin ilişkili bir örnek ifadesi olabilir.Furthermore, an event access may have an associated instance expression. Bir olay erişimi, += ve -= Işleçleri (olay atama) için sol taraftaki işlenen olarak görünebilir.An event access may appear as the left hand operand of the += and -= operators (Event assignment). Diğer bir bağlamda, olay erişimi olarak sınıflandırılan bir ifade, derleme zamanı hatasına neden olur.In any other context, an expression classified as an event access causes a compile-time error.
  • Dizin Oluşturucu erişimi.An indexer access. Her Dizin Oluşturucu erişiminin ilişkili bir türü vardır, yani dizin oluşturucunun öğe türü.Every indexer access has an associated type, namely the element type of the indexer. Ayrıca, Dizin Oluşturucu erişiminin ilişkili bir örnek ifadesi ve ilişkili bağımsız değişken listesi vardır.Furthermore, an indexer access has an associated instance expression and an associated argument list. Bir get set Dizin Oluşturucu erişiminin erişimcisi (veya bloğu) çağrıldığında, örnek ifadesinin değerlendirilme sonucu (Bu erişim) tarafından temsil edilen örnek olur this ve bağımsız değişkenlistesinin değerlendirilme sonucu, çağrının parametre listesi olur.When an accessor (the get or set block) of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access), and the result of evaluating the argument list becomes the parameter list of the invocation.
  • Hiçbir şey.Nothing. Bu, ifadesi dönüş türü olan bir yöntemin çağrılışında oluşur void .This occurs when the expression is an invocation of a method with a return type of void. Nothing olarak sınıflandırılan bir ifade yalnızca bir statement_expression (ifade deyimleri) bağlamında geçerlidir.An expression classified as nothing is only valid in the context of a statement_expression (Expression statements).

Bir ifadenin nihai sonucu hiçbir şekilde bir ad alanı, tür, Yöntem grubu veya olay erişimdir.The final result of an expression is never a namespace, type, method group, or event access. Bunun yerine, yukarıda belirtildiği gibi, bu ifade kategorileri yalnızca belirli bağlamlarda izin verilen ara yapılardır.Rather, as noted above, these categories of expressions are intermediate constructs that are only permitted in certain contexts.

Bir özellik erişimi veya Dizin Oluşturucu erişimi, Get erişimcisinin veya set erişimcisinin çağrılması gerçekleştirerek her zaman bir değer olarak yeniden sınıflanır.A property access or indexer access is always reclassified as a value by performing an invocation of the get accessor or the set accessor. Belirli erişimci, özelliğin veya dizin oluşturucunun erişim bağlamı tarafından belirlenir: erişim bir atamanın hedefi ise, küme erişimcisi yeni bir değer (basit atama) atamak için çağrılır.The particular accessor is determined by the context of the property or indexer access: If the access is the target of an assignment, the set accessor is invoked to assign a new value (Simple assignment). Aksi takdirde, get erişimcisi geçerli değeri (ifadelerin değerleri) almak için çağrılır.Otherwise, the get accessor is invoked to obtain the current value (Values of expressions).

İfadelerin değerleriValues of expressions

Bir ifadeyi içeren yapıların çoğu sonunda ifadenin bir değeri belirtmek için gereklidir.Most of the constructs that involve an expression ultimately require the expression to denote a value. Bu gibi durumlarda, gerçek ifade bir ad alanı, bir tür, bir yöntem grubu veya hiçbir şey ifade ediyorsa, derleme zamanı hatası oluşur.In such cases, if the actual expression denotes a namespace, a type, a method group, or nothing, a compile-time error occurs. Ancak, ifade bir özellik erişimi, Dizin Oluşturucu erişimi veya bir değişken ise, özelliğin, dizin oluşturucunun veya değişkenin değeri örtük olarak yerine kullanılır:However, if the expression denotes a property access, an indexer access, or a variable, the value of the property, indexer, or variable is implicitly substituted:

  • Bir değişkenin değeri, değişken tarafından tanımlanan depolama konumunda şu anda depolanan değer olacaktır.The value of a variable is simply the value currently stored in the storage location identified by the variable. Değerin alınabilmesi için bir değişken kesin olarak atanmış (kesin atama) olarak kabul edilmelidir, aksi takdirde bir derleme zamanı hatası oluşur.A variable must be considered definitely assigned (Definite assignment) before its value can be obtained, or otherwise a compile-time error occurs.
  • Özellik erişim ifadesinin değeri, özelliğin get erişimcisi çağrılarak elde edilir.The value of a property access expression is obtained by invoking the get accessor of the property. Özelliğin get erişimcisi yoksa, bir derleme zamanı hatası oluşur.If the property has no get accessor, a compile-time error occurs. Aksi takdirde, bir işlev üye çağrısı (dinamik aşırı yükleme çözümünün derleme zamanı denetimi) gerçekleştirilir ve çağrının sonucu özellik erişim ifadesinin değeri olur.Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed, and the result of the invocation becomes the value of the property access expression.
  • Dizin Oluşturucu erişim ifadesinin değeri, dizin oluşturucunun get erişimcisi çağrılarak elde edilir.The value of an indexer access expression is obtained by invoking the get accessor of the indexer. Dizin oluşturucunun get erişimcisi yoksa, bir derleme zamanı hatası oluşur.If the indexer has no get accessor, a compile-time error occurs. Aksi takdirde, Dizin Oluşturucu erişim ifadesiyle ilişkili bağımsız değişken listesiyle bir işlev üye çağrısı (dinamik aşırı yükleme çözümlemesi Için derleme zamanı denetimi) gerçekleştirilir ve çağrının sonucu Dizin Oluşturucu erişim ifadesinin değeri olur.Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed with the argument list associated with the indexer access expression, and the result of the invocation becomes the value of the indexer access expression.

Statik ve dinamik bağlamaStatic and Dynamic Binding

Bileşen ifadelerinin türü veya değerine (bağımsız değişkenler, işlenenler, alıcılar) göre bir işlemin anlamını belirleme işlemi genellikle bağlama olarak adlandırılır.The process of determining the meaning of an operation based on the type or value of constituent expressions (arguments, operands, receivers) is often referred to as binding. Örneğin, bir yöntem çağrısının anlamı alıcı ve bağımsız değişkenlerin türüne göre belirlenir.For instance the meaning of a method call is determined based on the type of the receiver and arguments. Bir işlecin anlamı, işlenenlerinin türüne göre belirlenir.The meaning of an operator is determined based on the type of its operands.

C# ' de bir işlemin anlamı genellikle derleme zamanında, onun bileşen ifadelerinin derleme zamanı türüne göre belirlenir.In C# the meaning of an operation is usually determined at compile-time, based on the compile-time type of its constituent expressions. Benzer şekilde, bir ifade hata içeriyorsa, hata algılanır ve derleyici tarafından raporlanır.Likewise, if an expression contains an error, the error is detected and reported by the compiler. Bu yaklaşım statik bağlama olarak bilinir.This approach is known as static binding.

Bununla birlikte, bir ifade dinamik bir ifadesiyse (yani türüne sahipse dynamic ) Bu, içinde yer aldığı herhangi bir bağlamanın, derleme zamanında sahip olduğu tür yerine çalışma zamanı türüne (örneğin, çalışma zamanında gösterdiği nesnenin gerçek türüne) göre olması gerektiğini belirtir.However, if an expression is a dynamic expression (i.e. has the type dynamic) this indicates that any binding that it participates in should be based on its run-time type (i.e. the actual type of the object it denotes at run-time) rather than the type it has at compile-time. Bu nedenle, bu tür bir işlemin bağlanması, programın çalışması sırasında işlemin gerçekleştirileceği zamana kadar ertelenir.The binding of such an operation is therefore deferred until the time where the operation is to be executed during the running of the program. Bu, dinamik bağlama olarak adlandırılır.This is referred to as dynamic binding.

Bir işlem dinamik olarak bağlandığında, derleyici tarafından çok az veya hiçbir denetim yapılmaz.When an operation is dynamically bound, little or no checking is performed by the compiler. Çalışma zamanı bağlama başarısız olursa, hatalar çalışma zamanında özel durum olarak bildirilir.Instead if the run-time binding fails, errors are reported as exceptions at run-time.

C# ' de aşağıdaki işlemler bağlamaya tabidir:The following operations in C# are subject to binding:

  • Üye erişimi: e.MMember access: e.M
  • Yöntem çağırma: e.M(e1, ..., eN)Method invocation: e.M(e1, ..., eN)
  • Temsilci çağrısı:e(e1, ..., eN)Delegate invocation:e(e1, ..., eN)
  • Öğe erişimi: e[e1, ..., eN]Element access: e[e1, ..., eN]
  • Nesne oluşturma: new C(e1, ..., eN)Object creation: new C(e1, ..., eN)
  • Aşırı yüklenmiş Birli İşleçler: + , - ,, ! ~ , ++ , -- , true , falseOverloaded unary operators: +, -, !, ~, ++, --, true, false
  • Aşırı yüklenmiş ikili işleçler: + , - ,, * / , % , & , && , | , || , ?? ,,, ^ << >> , == ,,, != > < , >= , <=Overloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=
  • Atama işleçleri: = , += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>=Assignment operators: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • Örtük ve açık dönüştürmelerImplicit and explicit conversions

Hiçbir dinamik ifade dahil edildiğinde, C# varsayılan statik bağlama olarak ayarlanır ve bu, bileşen ifadelerinin derleme zamanı türlerinin seçim sürecinde kullanıldığı anlamına gelir.When no dynamic expressions are involved, C# defaults to static binding, which means that the compile-time types of constituent expressions are used in the selection process. Ancak, yukarıda listelenen işlemler içindeki yapısal ifadelerden biri dinamik bir ifade olduğunda, işlem bunun yerine dinamik olarak bağlanır.However, when one of the constituent expressions in the operations listed above is a dynamic expression, the operation is instead dynamically bound.

Bağlama ZamanıBinding-time

Statik bağlama, derleme zamanında gerçekleşir, ancak dinamik bağlama çalışma zamanında gerçekleşir.Static binding takes place at compile-time, whereas dynamic binding takes place at run-time. Aşağıdaki bölümlerde, bağlama zamanı terimi, bağlamanın ne zaman gerçekleşdiğine bağlı olarak, derleme zamanı veya çalışma zamanı anlamına gelir.In the following sections, the term binding-time refers to either compile-time or run-time, depending on when the binding takes place.

Aşağıdaki örnek, statik ve dinamik bağlamanın ve bağlama zamanının önemli sayısını göstermektedir:The following example illustrates the notions of static and dynamic binding and of binding-time:

object  o = 5;
dynamic d = 5;

Console.WriteLine(5);  // static  binding to Console.WriteLine(int)
Console.WriteLine(o);  // static  binding to Console.WriteLine(object)
Console.WriteLine(d);  // dynamic binding to Console.WriteLine(int)

İlk iki çağrı statik olarak bağlanmıştır: öğesinin aşırı yüklemesi, Console.WriteLine bağımsız değişkeninin derleme zamanı türüne göre çekilir.The first two calls are statically bound: the overload of Console.WriteLine is picked based on the compile-time type of their argument. Bu nedenle, bağlama zamanı derleme zamanı olur.Thus, the binding-time is compile-time.

Üçüncü çağrı dinamik olarak bağlı: öğesinin aşırı yüklemesi, Console.WriteLine bağımsız değişkeninin çalışma zamanı türüne göre çekilir.The third call is dynamically bound: the overload of Console.WriteLine is picked based on the run-time type of its argument. Bu, bağımsız değişken dinamik bir ifade olduğu ve derleme zamanı türü olduğu için oluşur dynamic .This happens because the argument is a dynamic expression -- its compile-time type is dynamic. Bu nedenle, üçüncü çağrının bağlama zamanı çalışma zamanı olur.Thus, the binding-time for the third call is run-time.

Dinamik bağlamaDynamic binding

Dinamik bağlamanın amacı C# programlarının dinamik nesnelerle etkileşime geçmesini sağlamaktır, yani c# tür sisteminin normal kurallarını izlenmemiş nesneler.The purpose of dynamic binding is to allow C# programs to interact with dynamic objects, i.e. objects that do not follow the normal rules of the C# type system. Dinamik nesneler, farklı türlerde sistemlerle diğer programlama dillerinden nesneler olabilir veya farklı işlemler için kendi bağlama semantiğini uygulamak üzere programlı bir şekilde kurulum olan nesneler olabilir.Dynamic objects may be objects from other programming languages with different types systems, or they may be objects that are programmatically setup to implement their own binding semantics for different operations.

Dinamik bir nesnenin kendi semantiğini uyguladığı mekanizma uygulama tanımlı ' dır.The mechanism by which a dynamic object implements its own semantics is implementation defined. Verilen bir arabirim (yeniden tanımlanmış bir uygulama), dinamik nesneler tarafından, özel semantiklere sahip oldukları C# çalışma zamanına işaret etmek için uygulanır.A given interface -- again implementation defined -- is implemented by dynamic objects to signal to the C# run-time that they have special semantics. Bu nedenle, dinamik bir nesne üzerinde her işlem dinamik olarak bağlı olduğunda, bu belgede belirtilen C# yerine kendi bağlama semantiğine sahip olur.Thus, whenever operations on a dynamic object are dynamically bound, their own binding semantics, rather than those of C# as specified in this document, take over.

Dinamik bağlamanın amacı dinamik nesnelerle birlikte çalıştırılmasına izin verirken, C# dinamik olsa da olmasa da tüm nesnelerde dinamik bağlamaya izin verir.While the purpose of dynamic binding is to allow interoperation with dynamic objects, C# allows dynamic binding on all objects, whether they are dynamic or not. Bu, dinamik nesnelerin daha yumuşak bir şekilde tümleştirilmesini sağlar, çünkü bunlar üzerindeki işlemlerin sonuçları dinamik nesneler olmayabilir, ancak hala derleme zamanında programcıya bilinmeyen bir tür olabilir.This allows for a smoother integration of dynamic objects, as the results of operations on them may not themselves be dynamic objects, but are still of a type unknown to the programmer at compile-time. Ayrıca dinamik bağlama, hiçbir nesne dahil, dinamik nesneler olmasa bile hataya açık olan yansıma tabanlı kodu ortadan kaldırmaya yardımcı olabilir.Also dynamic binding can help eliminate error-prone reflection-based code even when no objects involved are dynamic objects.

Aşağıdaki bölümlerde, dinamik bağlama uygulandığında, her bir yapı için, dinamik bağlama uygulandığında, derleme zaman denetimi (varsa), varsa derleme zamanı ve ifade sınıflandırmasının ne olduğu ile ilgili olarak açıklanır.The following sections describe for each construct in the language exactly when dynamic binding is applied, what compile time checking -- if any -- is applied, and what the compile-time result and expression classification is.

Anayent ifadelerin türleriTypes of constituent expressions

Bir işlem statik olarak bağlandığında, bir bileşen ifadesinin türü (örn. bir alıcı, bir bağımsız değişken, bir dizin veya işlenen), her zaman bu ifadenin derleme zamanı türü olarak değerlendirilir.When an operation is statically bound, the type of a constituent expression (e.g. a receiver, an argument, an index or an operand) is always considered to be the compile-time type of that expression.

Bir işlem dinamik olarak bağlandığında, bileşen ifadesinin türü, bileşen ifadesinin derleme zamanı türüne bağlı olarak farklı yollarla belirlenir:When an operation is dynamically bound, the type of a constituent expression is determined in different ways depending on the compile-time type of the constituent expression:

  • Derleme zamanı türünün yapısal bir ifadesi, dynamic ifadenin çalışma zamanında değerlendirilen gerçek değer türüne sahip olarak kabul edilirA constituent expression of compile-time type dynamic is considered to have the type of the actual value that the expression evaluates to at runtime
  • Derleme zamanı türü bir tür parametresi olan bir anayent ifadesi tür parametresinin çalışma zamanında bağlı olduğu türe sahip olarak kabul edilirA constituent expression whose compile-time type is a type parameter is considered to have the type which the type parameter is bound to at runtime
  • Aksi halde, oluşturan ifade derleme zamanı türüne sahip olarak kabul edilir.Otherwise the constituent expression is considered to have its compile-time type.

İşleçlerOperators

İfadeler işlenenler _ ve _işleçlerinden*_ oluşturulur.Expressions are constructed from operands _ and _operators*_. Bir ifadenin işleçleri, işlenenlerin hangi işlemleri uygulanacağını gösterir.The operators of an expression indicate which operations to apply to the operands. İşleç örnekleri,, + , - _ ve içerir / new .Examples of operators include +, -, _, /, and new. İşlenenlerin örnekleri, sabit değerleri, alanları, yerel değişkenleri ve ifadeleri içerir.Examples of operands include literals, fields, local variables, and expressions.

Üç tür işleç vardır:There are three kinds of operators:

  • Birli İşleçler.Unary operators. Birli İşleçler bir işlenen alır ve önek gösterimini (gibi --x ) ya da sonek gösterimini (gibi x++ ) kullanır.The unary operators take one operand and use either prefix notation (such as --x) or postfix notation (such as x++).
  • İkili işleçler.Binary operators. İkili işleçler iki işlenen alır ve tüm kullanım yok gösterimini (gibi x + y ) kullanır.The binary operators take two operands and all use infix notation (such as x + y).
  • Üçlü işleç.Ternary operator. Yalnızca bir üçlü operatör, ?: var; üç işlenen alır ve indüzeltilme gösterimini ( c ? x : y ) kullanır.Only one ternary operator, ?:, exists; it takes three operands and uses infix notation (c ? x : y).

Bir ifadedeki işleçlerin değerlendirilme sırası, işleçlerin Öncelik _ ve _ ilişkilendirilebilirliği (işleç önceliği ve ilişkilendirilebilirliği) tarafından belirlenir.The order of evaluation of operators in an expression is determined by the precedence _ and _ associativity of the operators (Operator precedence and associativity).

Bir ifadedeki işlenenler soldan sağa değerlendirilir.Operands in an expression are evaluated from left to right. Örneğin, içinde F(i) + G(i++) * H(i) , yöntemi F eski değeri kullanılarak çağrılır i , yöntemi G eski değeriyle çağrılır i ve son olarak yöntemi H Yeni değeriyle çağrılır i .For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. Bu, ' den farklıdır ve işleç önceliğine ilgisiz değildir.This is separate from and unrelated to operator precedence.

Bazı işleçler aşırı yüklenebilir.Certain operators can be overloaded. İşleç aşırı yüklemesi, Kullanıcı tanımlı operatör uygulamalarının bir veya her ikisinin de Kullanıcı tanımlı sınıf veya yapı türünde (operatör aşırı yüklemesi) olduğu işlemler için belirtilmesine izin verir.Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type (Operator overloading).

İşleç önceliği ve ilişkilendirilebilirlikOperator precedence and associativity

Bir ifade birden çok işleç içerdiğinde, işleçlerin *önceliği _, bağımsız işleçlerin değerlendirildiği sırayı denetler.When an expression contains multiple operators, the *precedence _ of the operators controls the order in which the individual operators are evaluated. Örneğin * işleci, ikili + işlecinden daha yüksek önceliğe sahip olduğundan, x + y _ z ifadesi x + (y * z) olarak değerlendirilir.For example, the expression x + y _ z is evaluated as x + (y * z) because the * operator has higher precedence than the binary + operator. Bir işlecin önceliği, ilişkili olduğu dil bilgisi üretiminin tanımına göre belirlenir.The precedence of an operator is established by the definition of its associated grammar production. Örneğin, bir additive_expression , veya işleçleriyle ayrılmış multiplicative_expression s dizisinden oluşur + ve bu - sayede + ve - işleçleri * ,, / ve işleçlerinden daha düşük önceliğe sahiptir % .For example, an additive_expression consists of a sequence of multiplicative_expression s separated by + or - operators, thus giving the + and - operators lower precedence than the *, /, and % operators.

Aşağıdaki tablo, en yüksekten en düşüğe öncelik sırasına göre tüm işleçleri özetler:The following table summarizes all operators in order of precedence from highest to lowest:

SectionSection KategoriCategory İşleçlerOperators
Birincil ifadelerPrimary expressions BirincilPrimary x.y f(x) a[x] x++ x-- new typeof default checked unchecked delegatex.y f(x) a[x] x++ x-- new typeof default checked unchecked delegate
Birli işleçlerUnary operators BirliUnary + - ! ~ ++x --x (T)x+ - ! ~ ++x --x (T)x
Aritmetik işleçlerArithmetic operators ÇarpımsalMultiplicative * / %* / %
Aritmetik işleçlerArithmetic operators ToplamsalAdditive + -+ -
Kaydırma işleçleriShift operators ShiftShift << >><< >>
İlişkisel ve tür testi işleçleriRelational and type-testing operators İlişkisel ve tür testiRelational and type testing < > <= >= is as< > <= >= is as
İlişkisel ve tür testi işleçleriRelational and type-testing operators EşitlikEquality == !=== !=
Mantıksal işleçlerLogical operators Mantıksal VELogical AND &
Mantıksal işleçlerLogical operators Mantıksal XORLogical XOR ^
Mantıksal işleçlerLogical operators Mantıksal EĞERLogical OR |
Koşullu mantıksal işleçlerConditional logical operators Koşullu VEConditional AND &&
Koşullu mantıksal işleçlerConditional logical operators Koşullu VEYAConditional OR ||
Null birleştirme işleciThe null coalescing operator Null birleşimNull coalescing ??
Koşullu işleçConditional operator KoşulluConditional ?:
Atama işleçleri, anonim işlev ifadeleriAssignment operators, Anonymous function expressions Atama ve lambda ifadesiAssignment and lambda expression = *= /= %= += -= <<= >>= &= ^= |= =>= *= /= %= += -= <<= >>= &= ^= |= =>

Aynı önceliğe sahip iki işleç arasında bir işlenen gerçekleştiğinde, işleçlerin ilişkilendirilebilirliği, işlemlerin gerçekleştirileceği sırayı denetler:When an operand occurs between two operators with the same precedence, the associativity of the operators controls the order in which the operations are performed:

  • Atama işleçleri ve null birleşim işleci dışında, tüm ikili işleçler sola ilişkilendirilebilir, yani işlemler soldan sağa yapılır.Except for the assignment operators and the null coalescing operator, all binary operators are left-associative, meaning that operations are performed from left to right. Örneğin, x + y + z olarak değerlendirilir (x + y) + z .For example, x + y + z is evaluated as (x + y) + z.
  • Atama işleçleri, null birleştirme operatörü ve koşullu operatör ( ?: ), doğru ilişkilendirilebilir, yani işlemler sağdan sola yapılır.The assignment operators, the null coalescing operator and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. Örneğin, x = y = z olarak değerlendirilir x = (y = z) .For example, x = y = z is evaluated as x = (y = z).

Öncelik ve ilişkilendirilebilirlik, parantezler kullanılarak denetlenebilir.Precedence and associativity can be controlled using parentheses. Örneğin, ilk olarak ile x + y * z çarpar y z ve sonra sonucunu ekler x , ancak ilk olarak (x + y) * z sonucu ekler x ve y sonra sonucunu ile çarpar z .For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z.

İşleç aşırı yüklemesiOperator overloading

Tüm birli ve ikili işleçlerin, herhangi bir ifadede otomatik olarak kullanılabilen önceden tanımlanmış uygulamaları vardır.All unary and binary operators have predefined implementations that are automatically available in any expression. Önceden tanımlanmış uygulamalara ek olarak, Kullanıcı tanımlı uygulamalar operator sınıflardaki bildirimler ve yapılar (işleçler) dahil ederek tanıtılamaz.In addition to the predefined implementations, user-defined implementations can be introduced by including operator declarations in classes and structs (Operators). Kullanıcı tanımlı operatör uygulamaları, her zaman önceden tanımlanmış operatör uygulamalarından önceliklidir: yalnızca geçerli bir Kullanıcı tanımlı operatör uygulaması yoksa, birli operatör aşırı yükleme çözünürlüğü ve ikili işleç aşırı yükleme çözümlemesibölümünde açıklandığı gibi önceden tanımlanmış operatör uygulamaları göz önünde bulundurulacaktır.User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered, as described in Unary operator overload resolution and Binary operator overload resolution.

Fazla yüklenebilir Birli İşleçler şunlardır:The overloadable unary operators are:

+   -   !   ~   ++   --   true   false

Ancak true false ifadelerde açıkça kullanılmasa da (ve bu nedenle, işleç önceliği ve ilişkilendirilebilirliğiiçindeki öncelik tablosuna dahil edilmez), birkaç ifade bağlamlarında çağrıldıklarından işleçler kabul edilir: Boolean ifadeleri (Boole Ifadeleri) ve koşullu (koşullu işleç) ve koşullu mantıksal işleçler (koşullu işleci)içeren ifadeler.Although true and false are not used explicitly in expressions (and therefore are not included in the precedence table in Operator precedence and associativity), they are considered operators because they are invoked in several expression contexts: boolean expressions (Boolean expressions) and expressions involving the conditional (Conditional operator), and conditional logical operators (Conditional logical operators).

Fazla yüklenebilir ikili işleçler şunlardır:The overloadable binary operators are:

+   -   *   /   %   &   |   ^   <<   >>   ==   !=   >   <   >=   <=

Yalnızca yukarıda listelenen operatörler aşırı yüklenebilir.Only the operators listed above can be overloaded. Özellikle, üye erişimi, yöntem çağırma veya,,,,,, = && || ?? ?: => checked , unchecked , new , typeof , default as is ,,,,,,,,,, ve işleçlerini aşırı yüklemek mümkün değildir.In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ??, ?:, =>, checked, unchecked, new, typeof, default, as, and is operators.

İkili işleç aşırı yüklendiğinde, karşılık gelen atama işleci de dolaylı olarak aşırı yüklenmiştir.When a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded. Örneğin, işlecinin aşırı yüklemesi * aynı zamanda işlecin aşırı yüküne sahiptir *= .For example, an overload of operator * is also an overload of operator *=. Bu, bileşik atamadadaha ayrıntılı olarak açıklanmıştır.This is described further in Compound assignment. Atama işlecinin kendisinin ( = ) aşırı yüklü olamayacağını unutmayın.Note that the assignment operator itself (=) cannot be overloaded. Atama her zaman bir değeri bir değişkene basit bit temelinde bir kopyasını gerçekleştirir.An assignment always performs a simple bit-wise copy of a value into a variable.

Gibi dönüştürme işlemleri, (T)x Kullanıcı tanımlı dönüştürmeler (Kullanıcı tanımlı dönüştürmeler) sağlanarak aşırı yüklenmiştir.Cast operations, such as (T)x, are overloaded by providing user-defined conversions (User-defined conversions).

Gibi öğe erişimi, a[x] aşırı yüklenebilir bir operatör olarak kabul edilmez.Element access, such as a[x], is not considered an overloadable operator. Bunun yerine, Kullanıcı tanımlı dizin oluşturucular (Dizin oluşturucular) aracılığıyla desteklenir.Instead, user-defined indexing is supported through indexers (Indexers).

İfadelerde, işleçlere işleç gösterimi kullanılarak başvurulur ve bildirimlerinde, işlev gösterimi kullanılarak işleçlere başvurulur.In expressions, operators are referenced using operator notation, and in declarations, operators are referenced using functional notation. Aşağıdaki tabloda, birli ve ikili işleçler için işleç ve işlevsel gösterimler arasındaki ilişki gösterilmektedir.The following table shows the relationship between operator and functional notations for unary and binary operators. İlk girişte, op fazla yüklenebilir birli ön ek işlecini gösterir.In the first entry, op denotes any overloadable unary prefix operator. İkinci girişte, op birli sonek ++ ve -- işleçleri gösterir.In the second entry, op denotes the unary postfix ++ and -- operators. Üçüncü girişte, op , aşırı yüklenebilir ikili işleç olduğunu gösterir.In the third entry, op denotes any overloadable binary operator.

İşleç gösterimiOperator notation İşlevsel GösterimFunctional notation
op x operator op(x)
x op operator op(x)
x op y operator op(x,y)

Kullanıcı tanımlı işleç bildirimleri her zaman, işleç bildirimini içeren sınıf veya yapı türünde parametrelerden en az birini gerektirir.User-defined operator declarations always require at least one of the parameters to be of the class or struct type that contains the operator declaration. Bu nedenle, Kullanıcı tanımlı bir işlecin önceden tanımlanmış bir işleçle aynı imzaya sahip olması mümkün değildir.Thus, it is not possible for a user-defined operator to have the same signature as a predefined operator.

Kullanıcı tanımlı işleç bildirimleri bir işlecin sözdizimini, önceliğini veya ilişkilendirilebilirliğini değiştiremez.User-defined operator declarations cannot modify the syntax, precedence, or associativity of an operator. Örneğin, / işleci her zaman bir ikili işleçtir, her zaman işleç önceliği ve ilişkilendirilebilirliğiiçinde belirtilen öncelik düzeyine sahiptir ve her zaman sola ilişkilendirilebilir.For example, the / operator is always a binary operator, always has the precedence level specified in Operator precedence and associativity, and is always left-associative.

Kullanıcı tanımlı bir işlecin, kiralamaları yaptığı herhangi bir hesaplamayı gerçekleştirmesi mümkün olsa da, büyük bir süre içinde olması beklenen, farklı sonuçlar üreten uygulamalar kesinlikle önerilmez.While it is possible for a user-defined operator to perform any computation it pleases, implementations that produce results other than those that are intuitively expected are strongly discouraged. Örneğin, bir uygulama, operator == eşitlik için iki işleneni karşılaştırmalı ve uygun bir bool sonuç döndürmelidir.For example, an implementation of operator == should compare the two operands for equality and return an appropriate bool result.

Koşullu mantıksal işleçler aracılığıyla birincil ifadelerde bağımsız işleçlerin açıklamaları, işleçlerin önceden tanımlanmış uygulamalarını ve her bir operatör için uygulanan ek kuralları belirtir.The descriptions of individual operators in Primary expressions through Conditional logical operators specify the predefined implementations of the operators and any additional rules that apply to each operator. Açıklamalar birli operatör aşırı yükleme çözümü _, _ikili işleç aşırı yükleme çözümlemesi*_ ve _ sayısal yükseltme * terimleri, aşağıdaki bölümlerde bulunan tanımları kullanır.The descriptions make use of the terms unary operator overload resolution _, _binary operator overload resolution_, and _numeric promotion**, definitions of which are found in the following sections.

Birli operatör aşırı yükleme çözünürlüğüUnary operator overload resolution

op xYa da x op , daha op fazla yüklenebilir birli işleç olan ve türünde bir ifade olan bir işlem, x X aşağıdaki şekilde işlenir:An operation of the form op x or x op, where op is an overloadable unary operator, and x is an expression of type X, is processed as follows:

  • İşlem için tarafından sunulan aday Kullanıcı tanımlı operatörler kümesi, X operator op(x) aday Kullanıcı tanımlı işleçlerinkuralları kullanılarak belirlenir.The set of candidate user-defined operators provided by X for the operation operator op(x) is determined using the rules of Candidate user-defined operators.
  • Aday Kullanıcı tanımlı işleçler kümesi boş değilse, bu işlem için aday işleçler kümesi olur.If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Aksi halde, operator op yükseltilmemiş formları dahil olmak üzere önceden tanımlanmış birli uygulamalar, işlem için aday işleçler kümesi olur.Otherwise, the predefined unary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. Belirli bir işlecin önceden tanımlanmış uygulamaları, işlecinin açıklamasında belirtilir (birincil ifadeler ve Birli İşleçler).The predefined implementations of a given operator are specified in the description of the operator (Primary expressions and Unary operators).
  • Aşırı yükleme çözümlemesi çözüm kuralları, bağımsız değişken listesine göre en iyi işleci seçmek üzere aday işleçler kümesine uygulanır (x) ve bu işleç aşırı yükleme çözümleme işleminin sonucu olur.The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x), and this operator becomes the result of the overload resolution process. Aşırı yükleme çözümlemesi tek bir en iyi operatör seçmezse bağlama zamanı hatası oluşur.If overload resolution fails to select a single best operator, a binding-time error occurs.

İkili işleç aşırı yükleme çözümüBinary operator overload resolution

Formun bir işlemi, x op y op aşırı yüklenebilir bir ikili işleçtir, x türünde bir ifadedir X ve y türünde bir ifadedir, Y aşağıdaki şekilde işlenir:An operation of the form x op y, where op is an overloadable binary operator, x is an expression of type X, and y is an expression of type Y, is processed as follows:

  • Ve için tarafından sunulan aday Kullanıcı tanımlı operatörler kümesi X ve Y işlemi için operator op(x,y) belirlenir.The set of candidate user-defined operators provided by X and Y for the operation operator op(x,y) is determined. Küme, tarafından sunulan aday işleçleri birleşimi X ve tarafından sunulan aday işleçler, Y her biri aday Kullanıcı tanımlı işleçlerinkuralları kullanılarak belirlenir.The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of Candidate user-defined operators. XVe Y aynı türde veya ise X Y ortak bir temel türden türetildiyse, paylaşılan aday işleçler yalnızca Birleşik küme içinde bir kez gerçekleşir.If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once.
  • Aday Kullanıcı tanımlı işleçler kümesi boş değilse, bu işlem için aday işleçler kümesi olur.If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Aksi halde, operator op yükseltilmemiş formları dahil önceden tanımlanmış ikili uygulamalar, işlem için aday işleçler kümesi olur.Otherwise, the predefined binary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. Belirli bir işlecin önceden tanımlanmış uygulamaları, işlecinin açıklamasında belirtilir ( Koşullu mantıksal işleçleraracılığıylaAritmetik işleçler ).The predefined implementations of a given operator are specified in the description of the operator (Arithmetic operators through Conditional logical operators). Önceden tanımlanmış Enum ve temsilci işleçleri için kabul edilen tek işleçler, işlenenlerden birinin bağlama zamanı türü olan bir Enum veya temsilci türü tarafından tanımlananlar.For predefined enum and delegate operators, the only operators considered are those defined by an enum or delegate type that is the binding-time type of one of the operands.
  • Aşırı yükleme çözümlemesi çözüm kuralları, bağımsız değişken listesine göre en iyi işleci seçmek üzere aday işleçler kümesine uygulanır (x,y) ve bu işleç aşırı yükleme çözümleme işleminin sonucu olur.The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x,y), and this operator becomes the result of the overload resolution process. Aşırı yükleme çözümlemesi tek bir en iyi operatör seçmezse bağlama zamanı hatası oluşur.If overload resolution fails to select a single best operator, a binding-time error occurs.

Aday Kullanıcı tanımlı işleçlerCandidate user-defined operators

Bir tür ve bir işlem verildiğine T operator op(A) op göre, aşırı yüklenebilir bir işleçtir ve A bir bağımsız değişken listesidir, tarafından sağlanan aday Kullanıcı tanımlı operatörler T operator op(A) aşağıdaki gibi belirlenir:Given a type T and an operation operator op(A), where op is an overloadable operator and A is an argument list, the set of candidate user-defined operators provided by T for operator op(A) is determined as follows:

  • Türü saptayın T0 .Determine the type T0. TNull yapılabilir bir tür ise, T0 temel alınan türüdür, aksi durumda T0 değerine eşittir T .If T is a nullable type, T0 is its underlying type, otherwise T0 is equal to T.
  • İçindeki tüm operator op Bildirimler T0 ve bu tür operatörler için tüm yükseltilmemiş formlarında, en az bir operatör bağımsız değişken listesine göre uygulanabilir (uygulanabilir işlev üyesi) A , aday işleçler kümesi, içindeki tüm ilgili işleçlerden oluşur T0 .For all operator op declarations in T0 and all lifted forms of such operators, if at least one operator is applicable (Applicable function member) with respect to the argument list A, then the set of candidate operators consists of all such applicable operators in T0.
  • Aksi takdirde, T0 ise, object aday işleçleri kümesi boştur.Otherwise, if T0 is object, the set of candidate operators is empty.
  • Aksi takdirde, tarafından sunulan aday işleçleri kümesi T0 , öğesinin doğrudan temel sınıfı tarafından sunulan aday işleçler kümesidir T0 veya öğesinin etkin taban sınıfı T0 T0 bir tür parametresidir.Otherwise, the set of candidate operators provided by T0 is the set of candidate operators provided by the direct base class of T0, or the effective base class of T0 if T0 is a type parameter.

Sayısal yükseltmelerNumeric promotions

Sayısal yükseltme, önceden tanımlanmış birli ve ikili sayısal işleçlerin işlenenlerinin belirli örtük dönüştürmelerini otomatik olarak gerçekleştirmekten oluşur.Numeric promotion consists of automatically performing certain implicit conversions of the operands of the predefined unary and binary numeric operators. Sayısal yükseltme, farklı bir mekanizma değildir, ancak önceden tanımlanmış işleçlere aşırı yükleme çözümlemesi uygulamanın bir etkisi vardır.Numeric promotion is not a distinct mechanism, but rather an effect of applying overload resolution to the predefined operators. Sayısal yükseltme, Kullanıcı tanımlı işleçlerin benzer etkileri sergilemek üzere uygulanabilmesine rağmen özellikle Kullanıcı tanımlı işleçlerin değerlendirilmesini etkilemez.Numeric promotion specifically does not affect evaluation of user-defined operators, although user-defined operators can be implemented to exhibit similar effects.

Sayısal yükseltmede örnek olarak, ikili işlecin önceden tanımlanmış uygulamalarını göz önünde bulundurun * :As an example of numeric promotion, consider the predefined implementations of the binary * operator:

int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);

Bu işleç kümesine aşırı yükleme çözümleme kuralları (aşırı yükleme çözümlemesi) uygulandığında, efekt, örtük dönüştürmelerin işlenen türlerinden ilk birini seçmek için kullanılır.When overload resolution rules (Overload resolution) are applied to this set of operators, the effect is to select the first of the operators for which implicit conversions exist from the operand types. Örneğin, ve olduğu, b * s b ve olduğu byte s short , aşırı yükleme çözümlemesi operator *(int,int) en iyi operatör olarak seçilir.For example, for the operation b * s, where b is a byte and s is a short, overload resolution selects operator *(int,int) as the best operator. Bu nedenle, efekt, b ve s ' a dönüştürülür int ve sonucun türü olur int .Thus, the effect is that b and s are converted to int, and the type of the result is int. Benzer şekilde, ve olduğu gibi, i * d i int d double aşırı yükleme çözümlemesi operator *(double,double) en iyi operatör olarak seçilir.Likewise, for the operation i * d, where i is an int and d is a double, overload resolution selects operator *(double,double) as the best operator.

Tekli sayı yükseltmeleriUnary numeric promotions

Ön tanımlı + , - ve birli işleçlerin işlenenleri için birli sayısal yükseltme oluşur ~ .Unary numeric promotion occurs for the operands of the predefined +, -, and ~ unary operators. Birli sayısal yükseltme yalnızca,,, veya türündeki işlenenleri sbyte , byte türüne dönüştürmeyi içerir short ushort char int .Unary numeric promotion simply consists of converting operands of type sbyte, byte, short, ushort, or char to type int. Ayrıca, birli operatör için - , birli sayısal promosyon türündeki işlenenleri türüne dönüştürür uint long .Additionally, for the unary - operator, unary numeric promotion converts operands of type uint to type long.

İkili sayısal yükseltmelerBinary numeric promotions

Önceden tanımlanmış,,,,,,,,,, + - * / % & | ^ == != > , < ,, >= ve <= ikili işleçlerinin işlenenleri için ikili sayısal yükseltme oluşur.Binary numeric promotion occurs for the operands of the predefined +, -, *, /, %, &, |, ^, ==, !=, >, <, >=, and <= binary operators. İkili sayısal yükseltme, ilişkisel olmayan işleçler söz konusu olduğunda her iki işleneni dolaylı olarak ortak bir türe dönüştürür. bu da işlemin sonuç türü olur.Binary numeric promotion implicitly converts both operands to a common type which, in case of the non-relational operators, also becomes the result type of the operation. İkili sayısal yükseltme aşağıdaki kuralları, burada göründükleri düzende uygulamaktan oluşur:Binary numeric promotion consists of applying the following rules, in the order they appear here:

  • Her iki işlenen de tür ise decimal , diğer işlenen türüne dönüştürülür decimal veya diğer işlenen veya türünde ise bir bağlama zamanı hatası oluşur float double .If either operand is of type decimal, the other operand is converted to type decimal, or a binding-time error occurs if the other operand is of type float or double.
  • Aksi halde, her iki işlenen de tür ise double , diğer işlenen türüne dönüştürülür double .Otherwise, if either operand is of type double, the other operand is converted to type double.
  • Aksi halde, her iki işlenen de tür ise float , diğer işlenen türüne dönüştürülür float .Otherwise, if either operand is of type float, the other operand is converted to type float.
  • Aksi halde, her iki işlenen de tür ise ulong , diğer işlenen türüne dönüştürülür ulong veya diğer işlenen,, veya türünde ise bir bağlama zamanı hatası oluşur sbyte short int long .Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
  • Aksi halde, her iki işlenen de tür ise long , diğer işlenen türüne dönüştürülür long .Otherwise, if either operand is of type long, the other operand is converted to type long.
  • Aksi halde, her iki işlenen de tür ise uint ve diğer işlenen,, veya türünde ise, sbyte short int her iki işlenen de türüne dönüştürülür long .Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
  • Aksi halde, her iki işlenen de tür ise uint , diğer işlenen türüne dönüştürülür uint .Otherwise, if either operand is of type uint, the other operand is converted to type uint.
  • Aksi halde, her iki işlenen de türüne dönüştürülür int .Otherwise, both operands are converted to type int.

İlk kuralın decimal türü ve türleriyle karıştıraş tüm işlemlere izin vermez double float .Note that the first rule disallows any operations that mix the decimal type with the double and float types. Bu kural, decimal tür ve ve türleri arasında örtük dönüştürme olmadığı gerçeden sonraki bir şekildedir double float .The rule follows from the fact that there are no implicit conversions between the decimal type and the double and float types.

Ayrıca, ulong diğer işlenen işaretli bir integral türü olduğunda bir işlenenin türünden olması mümkün değildir.Also note that it is not possible for an operand to be of type ulong when the other operand is of a signed integral type. Bunun nedeni, tam aralığını ve imzalı integral türlerini temsil eden bir integral türü yok ulong .The reason is that no integral type exists that can represent the full range of ulong as well as the signed integral types.

Yukarıdaki her iki durumda da, bir işleneni açıkça diğer işlenenle uyumlu bir türe dönüştürmek için bir atama ifadesi kullanılabilir.In both of the above cases, a cast expression can be used to explicitly convert one operand to a type that is compatible with the other operand.

ÖrnekteIn the example

decimal AddPercent(decimal x, double percent) {
    return x * (1.0 + percent / 100.0);
}

bir bağlama zamanı hatası oluşur çünkü bir decimal , bir ile çarpılamıyor double .a binding-time error occurs because a decimal cannot be multiplied by a double. Hata, ikinci işlenenin şu şekilde olarak olarak dönüştürülmesiyle çözümlenir decimal :The error is resolved by explicitly converting the second operand to decimal, as follows:

decimal AddPercent(decimal x, double percent) {
    return x * (decimal)(1.0 + percent / 100.0);
}

Yükseltilmemiş işleçleriLifted operators

Yükseltilmemiş işleçleri , null olamayan değer türlerinde çalışan, önceden tanımlanmış ve Kullanıcı tanımlı işleçlere izin vererek bu türlerin null yapılabilir formlarla de kullanılmasını sağlar.Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Yükseltilmemiş işleçleri, aşağıda açıklandığı gibi, belirli gereksinimleri karşılayan önceden tanımlı ve Kullanıcı tanımlı işleçlerden oluşturulur:Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:

  • Birli İşleçler içinFor the unary operators

    +  ++  -  --  !  ~
    

    bir işlecin yükseltilmemiş formu, işlenen ve sonuç türleri null yapılamayan değer türleri ise vardır.a lifted form of an operator exists if the operand and result types are both non-nullable value types. Yükseltilmemiş formu, ? işlenene ve sonuç türlerine tek bir değiştirici eklenerek oluşturulur.The lifted form is constructed by adding a single ? modifier to the operand and result types. Yükseltilmemiş işleci, işlenen null ise null değeri üretir.The lifted operator produces a null value if the operand is null. Aksi takdirde, yükseltilmemiş işleci işleneni geri sarar, temeldeki işleci uygular ve sonucu sarmalar.Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.

  • İkili işleçler içinFor the binary operators

    +  -  *  /  %  &  |  ^  <<  >>
    

    bir işlecin yükseltilmemiş formu, işlenen ve sonuç türleri null yapılamayan tüm değer türleri ise vardır.a lifted form of an operator exists if the operand and result types are all non-nullable value types. Yükseltilmemiş formu, ? her bir işlenene ve sonuç türüne tek bir değiştirici eklenerek oluşturulur.The lifted form is constructed by adding a single ? modifier to each operand and result type. Yükseltilmemiş işleci, bir veya her iki işlenen de null ise ( & | bool? Boolean mantıksal işleçleriçinde açıklandığı gibi, türünün ve işleçleri için bir özel durum) null değer üretir.The lifted operator produces a null value if one or both operands are null (an exception being the & and | operators of the bool? type, as described in Boolean logical operators). Aksi halde, yükseltilmemiş işleci işlenenleri sarmalanmış, temeldeki işleci uygular ve sonucu sarmalar.Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result.

  • Eşitlik işleçleri içinFor the equality operators

    ==  !=
    

    bir işlecin yükseltilmemiş formu, işlenen türleri hem null yapılamayan değer türleri hem de sonuç türü ise vardır bool .a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. Yükseltilmemiş formu, her bir işlenen türüne tek bir ? değiştirici eklenerek oluşturulur.The lifted form is constructed by adding a single ? modifier to each operand type. Yükseltilmemiş işleci iki null değeri eşit kabul eder ve null olmayan bir değer null değeri boş değer olarak eşit değildir.The lifted operator considers two null values equal, and a null value unequal to any non-null value. Her iki işlenen de null değilse, yükseltilmemiş işleci işlenenleri kaldırır ve sonucu üretmek için temeldeki işleci uygular bool .If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

  • İlişkisel işleçler içinFor the relational operators

    <  >  <=  >=
    

    bir işlecin yükseltilmemiş formu, işlenen türleri hem null yapılamayan değer türleri hem de sonuç türü ise vardır bool .a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. Yükseltilmemiş formu, her bir işlenen türüne tek bir ? değiştirici eklenerek oluşturulur.The lifted form is constructed by adding a single ? modifier to each operand type. Yükseltilmemiş işleci, false bir veya her iki işlenen de null ise değeri üretir.The lifted operator produces the value false if one or both operands are null. Aksi halde, yükseltilmemiş işleci işlenenleri kaldırır ve sonucu üretmek için temeldeki işleci uygular bool .Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

Üye aramaMember lookup

Üye arama, bir tür bağlamındaki bir adın anlamını tespit eden işlemdir.A member lookup is the process whereby the meaning of a name in the context of a type is determined. Bir ifadede simple_name (basit adlar) veya bir member_access (üye erişimi) değerlendirme işleminin parçası olarak bir üye arama gerçekleşebilir.A member lookup can occur as part of evaluating a simple_name (Simple names) or a member_access (Member access) in an expression. Simple_name veya member_access bir invocation_expression (Yöntem etkinleştirmeleri) primary_expression olarak gerçekleşirse, üyenin çağrılması söylenir.If the simple_name or member_access occurs as the primary_expression of an invocation_expression (Method invocations), the member is said to be invoked.

Bir üye bir yöntem veya olaydır veya bir temsilci türünün (Temsilciler) ya da türün (dinamik tür) bir sabiti, alanı veya özelliği ise dynamic , üye ıncable olarak kabul edilir.If a member is a method or event, or if it is a constant, field or property of either a delegate type (Delegates) or the type dynamic (The dynamic type), then the member is said to be invocable.

Üye arama yalnızca bir üyenin adını değil, üyenin sahip olduğu tür parametrelerinin sayısını ve üyenin erişilebilir olup olmadığını dikkate alır.Member lookup considers not only the name of a member but also the number of type parameters the member has and whether the member is accessible. Üye arama amaçları için, genel metotlar ve iç içe geçmiş genel türler ilgili bildirimlerinde belirtilen tür parametrelerinin sayısına ve diğer tüm üyelerin sıfır tür parametrelerine sahip olması gerekir.For the purposes of member lookup, generic methods and nested generic types have the number of type parameters indicated in their respective declarations and all other members have zero type parameters.

Tür parametrelerine sahip bir adın üye  N araması K    T aşağıdaki şekilde işlenir:A member lookup of a name N with K type parameters in a type T is processed as follows:

  • İlk olarak, adlı bir erişilebilir üye kümesi  N belirlenir:First, a set of accessible members named N is determined:
    • TBir tür parametresi ise, kümesi, '  N de adlı erişilebilir Üyeler kümesiyle birlikte birincil kısıtlama veya ikincil kısıtlama (tür parametre kısıtlamaları) olarak belirtilen her türde erişilebilir üye kümelerinin birleşimidir  T  N object .If T is a type parameter, then the set is the union of the sets of accessible members named N in each of the types specified as a primary constraint or secondary constraint (Type parameter constraints) for T, along with the set of accessible members named N in object.
    • Aksi takdirde, küme,  N  T devralınan Üyeler ve ' de adlı erişilebilir Üyeler dahil olmak üzere, içindeki adlı tüm erişilebilir (üye erişim) üyelerinden oluşur  N object .Otherwise, the set consists of all accessible (Member access) members named N in T, including inherited members and the accessible members named N in object. TOluşturulmuş bir türse, Üyeler kümesi, oluşturulan türlerin üyelerindeaçıklanan tür bağımsız değişkenlerinin yerine alınır.If T is a constructed type, the set of members is obtained by substituting type arguments as described in Members of constructed types. Değiştirici içeren Üyeler override , kümeden çıkarılır.Members that include an override modifier are excluded from the set.
  • Sonra, K sıfır ise, bildirimleri tür parametreleri içeren tüm iç içe türler kaldırılır.Next, if K is zero, all nested types whose declarations include type parameters are removed. KSıfır değilse, farklı sayıda tür parametrelerine sahip tüm Üyeler kaldırılır.If K is not zero, all members with a different number of type parameters are removed. KSıfır olduğunda, tür çıkarımı işlemi (tür çıkarımı) tür bağımsız değişkenlerini çıkarsanbileceği için tür parametrelerine sahip yöntemlerin kaldırılmadığını unutmayın.Note that when K is zero, methods having type parameters are not removed, since the type inference process (Type inference) might be able to infer the type arguments.
  • Sonra, üye çağrılırsa,çağrılamayan tüm Üyeler kümeden kaldırılır.Next, if the member is invoked, all non-invocable members are removed from the set.
  • Daha sonra, diğer Üyeler tarafından gizlenen Üyeler kümeden kaldırılır.Next, members that are hidden by other members are removed from the set. Küme içindeki her üye için S.M , S üyenin bildirildiği tür,  M aşağıdaki kurallar uygulanır:For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied:
    • MBir sabit, alan, özellik, olay veya numaralandırma üyesiyse, taban türünde belirtilen tüm Üyeler S kümeden kaldırılır.If M is a constant, field, property, event, or enumeration member, then all members declared in a base type of S are removed from the set.
    • MBir tür bildirimidir, temel türünde belirtilen tüm tür olmayan türler S kümeden kaldırılır ve temel türünde bildirildiği gibi aynı sayıda tür parametrelerine sahip tüm tür bildirimleri kümeden M S kaldırılır.If M is a type declaration, then all non-types declared in a base type of S are removed from the set, and all type declarations with the same number of type parameters as M declared in a base type of S are removed from the set.
    • MBir yöntem ise, taban türünde belirtilen tüm yöntem olmayan üyeler S kümeden kaldırılır.If M is a method, then all non-method members declared in a base type of S are removed from the set.
  • Daha sonra, sınıf üyeleri tarafından gizlenen arabirim üyeleri kümeden kaldırılır.Next, interface members that are hidden by class members are removed from the set. Bu adım yalnızca T bir tür parametresi ise ve T object boş olmayan bir etkin arabirim kümesi (tür parametresi kısıtlamaları) dışında bir etkin taban sınıfa sahipse bir etkiye sahiptir.This step only has an effect if T is a type parameter and T has both an effective base class other than object and a non-empty effective interface set (Type parameter constraints). Küme içindeki her üye için S.M , S üyenin bildirildiği tür olduğu, M Şu kuralların dışında S bir sınıf bildirimidir object :For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied if S is a class declaration other than object:
    • MBir sabit, alan, özellik, olay, numaralandırma üyesi veya tür bildirimidir, bir arabirim bildiriminde belirtilen tüm Üyeler kümeden kaldırılır.If M is a constant, field, property, event, enumeration member, or type declaration, then all members declared in an interface declaration are removed from the set.
    • MBir yöntem ise, bir arabirim bildiriminde belirtilen tüm yöntem olmayan Üyeler kümeden kaldırılır ve bir arabirim bildiriminde bildirildiği şekilde aynı imzaya sahip tüm yöntemler M kümeden kaldırılır.If M is a method, then all non-method members declared in an interface declaration are removed from the set, and all methods with the same signature as M declared in an interface declaration are removed from the set.
  • Son olarak, gizli üyeleri kaldırdıkça, aramanın sonucu belirlenir:Finally, having removed hidden members, the result of the lookup is determined:
    • Küme, yöntem olmayan tek bir üyenin içeriyorsa, bu üye aramanın sonucudur.If the set consists of a single member that is not a method, then this member is the result of the lookup.
    • Aksi takdirde, küme yalnızca yöntemleri içeriyorsa, bu yöntem grubu aramanın sonucudur.Otherwise, if the set contains only methods, then this group of methods is the result of the lookup.
    • Aksi takdirde, arama belirsizdir ve bir bağlama zamanı hatası oluşur.Otherwise, the lookup is ambiguous, and a binding-time error occurs.

Tür parametreleri ve arabirimleri dışındaki türlerde üye aramaları ve kesinlikle tek devralma olan arabirimlerde üye aramaları için (devralma zincirindeki her arabirim tam olarak sıfır veya bir doğrudan temel arabirimine sahiptir), arama kurallarının etkisi yalnızca türetilmiş üyelerin aynı ad veya imzaya sahip temel üyeleri gizlemesini içerir.For member lookups in types other than type parameters and interfaces, and member lookups in interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature. Bu tür tek devralma aramaları hiçbir şekilde belirsiz değildir.Such single-inheritance lookups are never ambiguous. Birden çok devralma arabirimindeki üye aramalarından muhtemelen olabilecek belirsizlikleri, arabirim üye erişimibölümünde açıklanmıştır.The ambiguities that can possibly arise from member lookups in multiple-inheritance interfaces are described in Interface member access.

Taban türleriBase types

Üye arama amaçları doğrultusunda, bir tür T Aşağıdaki taban türlerine sahip olduğu kabul edilir:For purposes of member lookup, a type T is considered to have the following base types:

  • Tİse object , T temel türe sahip değildir.If T is object, then T has no base type.
  • TBir enum_type ise, taban türleri, T ve sınıflardır System.Enum System.ValueType object .If T is an enum_type, the base types of T are the class types System.Enum, System.ValueType, and object.
  • TBir struct_type ise, taban türleri T sınıf türlerdir System.ValueType ve object .If T is a struct_type, the base types of T are the class types System.ValueType and object.
  • TBir class_type ise, temel türleri T T sınıf türü de dahil olmak üzere temel sınıflardır object .If T is a class_type, the base types of T are the base classes of T, including the class type object.
  • TBir interface_type ise, taban türleri T temel arayüzlerdir T ve sınıf türüdür object .If T is an interface_type, the base types of T are the base interfaces of T and the class type object.
  • TBir array_type ise, taban türleri T sınıf türlerdir System.Array ve object .If T is an array_type, the base types of T are the class types System.Array and object.
  • TBir delegate_type ise, taban türleri T sınıf türlerdir System.Delegate ve object .If T is a delegate_type, the base types of T are the class types System.Delegate and object.

İşlev üyeleriFunction members

İşlev üyeleri, çalıştırılabilir deyimler içeren üyeleridir.Function members are members that contain executable statements. İşlev üyeleri her zaman türlerin üyeleridir ve ad alanlarının üyeleri olamaz.Function members are always members of types and cannot be members of namespaces. C#, işlev üyelerinin aşağıdaki kategorilerini tanımlar:C# defines the following categories of function members:

  • YöntemlerMethods
  • ÖzelliklerProperties
  • EkinliklerEvents
  • Dizin OluşturucularIndexers
  • Kullanıcı tanımlı işleçlerUser-defined operators
  • Örnek oluşturucularInstance constructors
  • Statik oluşturucularStatic constructors
  • YıkıcılarDestructors

Yok ediciler ve statik oluşturucular dışında (açıkça çağrılamaz), işlev üyelerinde bulunan deyimler işlev üyesi etkinleştirmeleri aracılığıyla yürütülür.Except for destructors and static constructors (which cannot be invoked explicitly), the statements contained in function members are executed through function member invocations. İşlev üye çağrısı yazmak için gerçek sözdizimi, belirli bir işlev üyesi kategorisine bağlıdır.The actual syntax for writing a function member invocation depends on the particular function member category.

İşlev üyesi çağırma işlevinin bağımsız değişken listesi (bağımsız değişken listeleri), işlev üyesinin parametreleri için gerçek değerler veya değişken başvuruları sağlar.The argument list (Argument lists) of a function member invocation provides actual values or variable references for the parameters of the function member.

Genel yöntemlerin etkinleştirmeleri, yönteme geçirilecek tür bağımsız değişkenleri kümesini belirlemede tür çıkarımı kullanabilir.Invocations of generic methods may employ type inference to determine the set of type arguments to pass to the method. Bu işlem tür çıkarımıbölümünde açıklanmaktadır.This process is described in Type inference.

Yöntemler, Dizin oluşturucular, işleçler ve örnek oluşturucuların çağırmaları, hangi bir tür üye kümesinin çalıştırılacağını belirleyen aşırı yükleme çözümlemesi sağlar.Invocations of methods, indexers, operators and instance constructors employ overload resolution to determine which of a candidate set of function members to invoke. Bu işlem aşırı yükleme çözümlemesibölümünde açıklanmaktadır.This process is described in Overload resolution.

Bağlama zamanında belirli bir işlev üyesi tanımlandıktan sonra, muhtemelen aşırı yükleme çözünürlüğü aracılığıyla işlev üyesini çağırma işleminin gerçek çalışma zamanı denetimi, dinamik aşırı yükleme çözümünün derleme zamanı denetimindeaçıklanmaktadır.Once a particular function member has been identified at binding-time, possibly through overload resolution, the actual run-time process of invoking the function member is described in Compile-time checking of dynamic overload resolution.

Aşağıdaki tabloda, açıkça çağrılabilen işlev üyelerinin altı kategorisini içeren yapılar içinde gerçekleşen işlem özetlenmektedir.The following table summarizes the processing that takes place in constructs involving the six categories of function members that can be explicitly invoked. ,,, Ve ' de,,,, e x y ve value değişkenler veya değerler olarak sınıflandırılan ifadeleri belirtin, T tür olarak sınıflandırılan bir ifadeyi belirtir, F yöntemin basit adıdır ve P bir özelliğin basit adıdır.In the table, e, x, y, and value indicate expressions classified as variables or values, T indicates an expression classified as a type, F is the simple name of a method, and P is the simple name of a property.

OluşturConstruct ÖrnekExample AçıklamaDescription
Yöntem çağırmaMethod invocation F(x,y) Aşırı yükleme çözümlemesi, F kapsayan sınıf veya yapıda en iyi yöntemi seçmek için uygulanır.Overload resolution is applied to select the best method F in the containing class or struct. Yöntemi bağımsız değişken listesiyle çağrılır (x,y) .The method is invoked with the argument list (x,y). Yöntem değilse static , örnek ifadesi olur this .If the method is not static, the instance expression is this.
T.F(x,y) Sınıf veya yapıda en iyi yöntemi seçmek için aşırı yükleme çözümlemesi uygulanır F T .Overload resolution is applied to select the best method F in the class or struct T. Yöntem değilse bir bağlama zamanı hatası oluşur static .A binding-time error occurs if the method is not static. Yöntemi bağımsız değişken listesiyle çağrılır (x,y) .The method is invoked with the argument list (x,y).
e.F(x,y) Sınıf, yapı veya tür tarafından verilen arabirimdeki en iyi yöntem F 'yi seçmek için aşırı yükleme çözümlemesi uygulanır e .Overload resolution is applied to select the best method F in the class, struct, or interface given by the type of e. Yöntemi ise bağlama zamanı hatası oluşur static .A binding-time error occurs if the method is static. Yöntemi, örnek ifadesiyle e ve bağımsız değişken listesiyle çağrılır (x,y) .The method is invoked with the instance expression e and the argument list (x,y).
Özellik erişimiProperty access P get P Kapsayan sınıf veya yapı içindeki özelliğin erişimcisi çağrıldı.The get accessor of the property P in the containing class or struct is invoked. Derleme zamanı hatası P , salt yazılır ise oluşur.A compile-time error occurs if P is write-only. Değilse P static , örnek ifadesi olur this .If P is not static, the instance expression is this.
P = value set P Kapsayıcı sınıf veya yapı içindeki özelliğin erişimcisi bağımsız değişken listesiyle çağrılır (value) .The set accessor of the property P in the containing class or struct is invoked with the argument list (value). Salt okunurdur derleme zamanı hatası oluşur P .A compile-time error occurs if P is read-only. Değilse P static , örnek ifadesi olur this .If P is not static, the instance expression is this.
T.P get P Sınıf veya yapı içindeki özelliğin erişimcisi T çağrılır.The get accessor of the property P in the class or struct T is invoked. Bir derleme zamanı hatası, yoksa veya salt yazılır ise oluşur P static P .A compile-time error occurs if P is not static or if P is write-only.
T.P = value set P Sınıf veya yapı içindeki özelliğin erişimcisi T bağımsız değişken listesiyle çağrılır (value) .The set accessor of the property P in the class or struct T is invoked with the argument list (value). Bir derleme zamanı hatası P , değilse static veya P salt okunurdur oluşur.A compile-time error occurs if P is not static or if P is read-only.
e.P get P Sınıf, yapı veya tür tarafından verilen arabirimdeki özelliğin erişimcisi e örnek ifadesiyle çağrılır e .The get accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e. Varsa veya varsa bağlama zamanı hatası oluşur P static P .A binding-time error occurs if P is static or if P is write-only.
e.P = value set P Türü tarafından verilen sınıf, yapı veya arabirimdeki özelliğin erişimcisi, e örnek ifadesiyle e ve bağımsız değişken listesiyle çağrılır (value) .The set accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e and the argument list (value). Varsa P static veya salt okunurdur bir bağlama zamanı hatası oluşur P .A binding-time error occurs if P is static or if P is read-only.
Olay erişimiEvent access E += value add E Kapsayan sınıf veya yapı içindeki olayın erişimcisi çağrıldı.The add accessor of the event E in the containing class or struct is invoked. EStatik değilse, örnek ifadesi olur this .If E is not static, the instance expression is this.
E -= value remove E Kapsayan sınıf veya yapı içindeki olayın erişimcisi çağrıldı.The remove accessor of the event E in the containing class or struct is invoked. EStatik değilse, örnek ifadesi olur this .If E is not static, the instance expression is this.
T.E += value add E Sınıf veya yapı içindeki olayın erişimcisi T çağrılır.The add accessor of the event E in the class or struct T is invoked. Statik değilse bir bağlama zamanı hatası oluşur E .A binding-time error occurs if E is not static.
T.E -= value remove E Sınıf veya yapı içindeki olayın erişimcisi T çağrılır.The remove accessor of the event E in the class or struct T is invoked. Statik değilse bir bağlama zamanı hatası oluşur E .A binding-time error occurs if E is not static.
e.E += value add E Sınıf, yapı veya tür tarafından verilen arabirimdeki olayın erişimcisi e örnek ifadesiyle çağrılır e .The add accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. Statik ise bağlama zamanı hatası oluşur E .A binding-time error occurs if E is static.
e.E -= value remove E Sınıf, yapı veya tür tarafından verilen arabirimdeki olayın erişimcisi e örnek ifadesiyle çağrılır e .The remove accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. Statik ise bağlama zamanı hatası oluşur E .A binding-time error occurs if E is static.
Dizin Oluşturucu erişimiIndexer access e[x,y] Aşırı yükleme çözümlemesi, sınıf, yapı veya e-postayla verilen arabirimdeki en iyi Dizin oluşturucuyu seçmek için uygulanır.Overload resolution is applied to select the best indexer in the class, struct, or interface given by the type of e. getDizin oluşturucunun erişimcisi, örnek ifadesiyle e ve bağımsız değişken listesiyle çağrılır (x,y) .The get accessor of the indexer is invoked with the instance expression e and the argument list (x,y). Dizin Oluşturucu salt yazılır ise bağlama zamanı hatası oluşur.A binding-time error occurs if the indexer is write-only.
e[x,y] = value Sınıf, yapı veya tür tarafından verilen arabirimdeki en iyi Dizin oluşturucuyu seçmek için aşırı yükleme çözümlemesi uygulanır e .Overload resolution is applied to select the best indexer in the class, struct, or interface given by the type of e. setDizin oluşturucunun erişimcisi, örnek ifadesiyle e ve bağımsız değişken listesiyle çağrılır (x,y,value) .The set accessor of the indexer is invoked with the instance expression e and the argument list (x,y,value). Dizin Oluşturucu salt okunurdur bağlama zamanı hatası oluşur.A binding-time error occurs if the indexer is read-only.
İşleç çağırmaOperator invocation -x Öğesinin türü tarafından verilen sınıfta veya yapıda en iyi birli işleci seçmek için aşırı yükleme çözümlemesi uygulanır x .Overload resolution is applied to select the best unary operator in the class or struct given by the type of x. Seçili operatör bağımsız değişken listesiyle çağrılır (x) .The selected operator is invoked with the argument list (x).
x + y Ve türleri tarafından verilen sınıflarda veya yapılarda en iyi ikili işleci seçmek için aşırı yükleme çözümlemesi uygulanır x y .Overload resolution is applied to select the best binary operator in the classes or structs given by the types of x and y. Seçili operatör bağımsız değişken listesiyle çağrılır (x,y) .The selected operator is invoked with the argument list (x,y).
Örnek Oluşturucu çağrısıInstance constructor invocation new T(x,y) Sınıf veya yapı biriminde en iyi örnek oluşturucusunu seçmek için aşırı yükleme çözümlemesi uygulanır T .Overload resolution is applied to select the best instance constructor in the class or struct T. Örnek Oluşturucu bağımsız değişken listesiyle çağrılır (x,y) .The instance constructor is invoked with the argument list (x,y).

Bağımsız değişken listeleriArgument lists

Her işlev üyesi ve temsilci çağrısı, işlev üyesinin parametreleri için gerçek değerler veya değişken başvuruları sağlayan bir bağımsız değişken listesi içerir.Every function member and delegate invocation includes an argument list which provides actual values or variable references for the parameters of the function member. İşlev üyesi çağrısının bağımsız değişken listesini belirtmek için sözdizimi, işlev üyesi kategorisine bağlıdır:The syntax for specifying the argument list of a function member invocation depends on the function member category:

  • Örnek oluşturucular, Yöntemler, Dizin oluşturucular ve temsilciler için bağımsız değişkenler, aşağıda açıklandığı gibi argument_list olarak belirtilir.For instance constructors, methods, indexers and delegates, the arguments are specified as an argument_list, as described below. Dizin oluşturucular için, erişimci çağrılırken set bağımsız değişken listesi, atama işlecinin sağ işleneni olarak belirtilen ifadeyi de içerir.For indexers, when invoking the set accessor, the argument list additionally includes the expression specified as the right operand of the assignment operator.
  • Özellikler için, erişimci çağrılırken bağımsız değişken listesi boştur get ve erişimci çağrılırken atama işlecinin sağ işleneni olarak belirtilen ifadeden oluşur set .For properties, the argument list is empty when invoking the get accessor, and consists of the expression specified as the right operand of the assignment operator when invoking the set accessor.
  • Olaylar için bağımsız değişken listesi, veya işlecinin sağ işleneni olarak belirtilen ifadeden oluşur += -= .For events, the argument list consists of the expression specified as the right operand of the += or -= operator.
  • Kullanıcı tanımlı işleçler için bağımsız değişken listesi birli işlecin tek işleneninden veya ikili işlecinin iki işleneninden oluşur.For user-defined operators, the argument list consists of the single operand of the unary operator or the two operands of the binary operator.

Özelliklerinin bağımsız değişkenleri (Özellikler), Olaylar (Olaylar) ve Kullanıcı tanımlı işleçler (işleçler) her zaman değer parametreleri olarak geçirilir (değer parametreleri).The arguments of properties (Properties), events (Events), and user-defined operators (Operators) are always passed as value parameters (Value parameters). Dizin oluşturucularının bağımsız değişkenleri (Dizin oluşturucular) her zaman değer parametreleri (değer parametreleri) veya parametre dizileri (parametre dizileri) olarak geçirilir.The arguments of indexers (Indexers) are always passed as value parameters (Value parameters) or parameter arrays (Parameter arrays). Başvuru ve çıkış parametreleri bu işlev üyesi kategorileri için desteklenmez.Reference and output parameters are not supported for these categories of function members.

Örnek oluşturucusunun, yöntemin, dizin oluşturucunun veya temsilci çağrısının bağımsız değişkenleri argument_list olarak belirtilir:The arguments of an instance constructor, method, indexer or delegate invocation are specified as an argument_list:

argument_list
    : argument (',' argument)*
    ;

argument
    : argument_name? argument_value
    ;

argument_name
    : identifier ':'
    ;

argument_value
    : expression
    | 'ref' variable_reference
    | 'out' variable_reference
    ;

Argument_list , virgülle ayrılmış bir veya daha fazla bağımsız değişkenden oluşur.An argument_list consists of one or more argument s, separated by commas. Her bağımsız değişken, bir argument_value ve ardından bir isteğe bağlı argument_name oluşur.Each argument consists of an optional argument_name followed by an argument_value. Argument_name bir bağımsız değişken *adlandırılmış bağımsız değişken _ olarak adlandırılır, ancak *argument_name* olmayan bir bağımsız değişken * bir *konumsal bağımsız değişkenidir.An argument with an argument_name is referred to as a named argument _, whereas an _argument without an argument_name is a *positional argument_. Bir Konumsal bağımsız değişkenin bir _argument_list * içindeki adlandırılmış bir bağımsız değişkenden sonra görünmesi hatadır.It is an error for a positional argument to appear after a named argument in an _argument_list*.

Argument_value aşağıdaki formlardan birini alabilir:The argument_value can take one of the following forms:

  • Bağımsız değişkenin değer parametresi olarak geçtiğini belirten bir ifade(değer parametreleri).An expression, indicating that the argument is passed as a value parameter (Value parameters).
  • refBağımsız değişkenin bir başvuru parametresi olarak geçtiğini belirten bir variable_reference (değişken başvuruları) ve anahtar sözcüğü (başvuru parametreleri).The keyword ref followed by a variable_reference (Variable references), indicating that the argument is passed as a reference parameter (Reference parameters). Bir değişken başvuru parametresi olarak geçirilebilmesi için kesinlikle atanmalı (kesin atama).A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter. Anahtar sözcüğünün out ardından bir variable_reference (değişken başvuruları), bağımsız değişkenin bir çıkış parametresi olarak geçtiğini belirtir (çıkış parametreleri).The keyword out followed by a variable_reference (Variable references), indicating that the argument is passed as an output parameter (Output parameters). Değişken, değişkenin çıkış parametresi olarak geçirildiği bir işlev üyesi çağrısı sonrasında kesin olarak atanmış (kesin atama) olarak değerlendirilir.A variable is considered definitely assigned (Definite assignment) following a function member invocation in which the variable is passed as an output parameter.

Karşılık gelen parametrelerCorresponding parameters

Bir bağımsız değişken listesindeki her bağımsız değişken için, çağrılan işlev üyesinde veya temsilde karşılık gelen bir parametre olması gerekmez.For each argument in an argument list there has to be a corresponding parameter in the function member or delegate being invoked.

Aşağıda kullanılan parametre listesi aşağıdaki şekilde belirlenir:The parameter list used in the following is determined as follows:

  • Sınıflarda tanımlı sanal yöntemler ve Dizin oluşturucular için, parametre listesi, alıcı türü ve temel sınıfları arasında arama yaparak işlev üyesinin en belirgin bildiriminden veya geçersiz kılınmadan çekilir.For virtual methods and indexers defined in classes, the parameter list is picked from the most specific declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes.
  • Arabirim yöntemleri ve Dizin oluşturucular için, parametre listesi, arabirim türü ile başlayıp temel arabirimler üzerinden arama yaparak üyenin en belirli tanımını oluşturacak şekilde çekilir.For interface methods and indexers, the parameter list is picked form the most specific definition of the member, starting with the interface type and searching through the base interfaces. Benzersiz bir parametre listesi bulunamazsa, erişilemeyen adlara sahip bir parametre listesi ve isteğe bağlı parametre oluşturulur; bu nedenle, etkinleştirmeleri adlandırılmış parametreleri kullanamaz veya isteğe bağlı bağımsız değişkenleri alamaz.If no unique parameter list is found, a parameter list with inaccessible names and no optional parameters is constructed, so that invocations cannot use named parameters or omit optional arguments.
  • Kısmi yöntemler için, tanımlayan kısmi Yöntem bildiriminin parametre listesi kullanılır.For partial methods, the parameter list of the defining partial method declaration is used.
  • Diğer tüm işlev üyeleri ve temsilciler için yalnızca tek bir parametre listesi bulunur ve bu, kullanılır.For all other function members and delegates there is only a single parameter list, which is the one used.

Bir bağımsız değişkenin veya parametrenin konumu, bağımsız değişken listesi veya parametre listesinde kendisinden önceki bağımsız değişken veya parametre sayısı olarak tanımlanır.The position of an argument or parameter is defined as the number of arguments or parameters preceding it in the argument list or parameter list.

İşlev üyesi bağımsız değişkenleri için karşılık gelen parametreler şu şekilde oluşturulur:The corresponding parameters for function member arguments are established as follows:

  • Örnek oluşturucular, Yöntemler, Dizin oluşturucular ve temsilciler argument_list bağımsız değişkenler:Arguments in the argument_list of instance constructors, methods, indexers and delegates:
    • Parametre listesindeki aynı konumda sabit bir parametrenin gerçekleştiği konumsal bir bağımsız değişken bu parametreye karşılık gelir.A positional argument where a fixed parameter occurs at the same position in the parameter list corresponds to that parameter.
    • Normal biçiminde çağrılan bir parametre dizisi olan bir işlev üyesinin Konumsal bağımsız değişkeni, parametre listesinde aynı konumda olması gereken parametre dizisine karşılık gelir.A positional argument of a function member with a parameter array invoked in its normal form corresponds to the parameter array, which must occur at the same position in the parameter list.
    • Bir parametre dizisi olan bir işlev üyesinin, parametre listesinde aynı konumda hiçbir sabit parametre gerçekleşmediği, parametre dizisindeki bir öğeye karşılık gelen bir konum bağımsız değişkeni.A positional argument of a function member with a parameter array invoked in its expanded form, where no fixed parameter occurs at the same position in the parameter list, corresponds to an element in the parameter array.
    • Adlandırılmış bir bağımsız değişken, parametre listesinde aynı ada sahip parametreye karşılık gelir.A named argument corresponds to the parameter of the same name in the parameter list.
    • Dizin oluşturucular için, erişimci çağrılırken, set atama işlecinin sağ işleneni olarak belirtilen ifade, value erişimci bildiriminin örtük parametresine karşılık gelir set .For indexers, when invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
  • Özellikler için, get erişimci çağrılırken bağımsız değişken yoktur.For properties, when invoking the get accessor there are no arguments. setErişimci çağrılırken, atama işlecinin sağ işleneni olarak belirtilen ifade, value erişimci bildiriminin örtük parametresine karşılık gelir set .When invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
  • Kullanıcı tanımlı Birli İşleçler (dönüşümler dahil) için, tek işlenen işleç bildiriminin tek parametresine karşılık gelir.For user-defined unary operators (including conversions), the single operand corresponds to the single parameter of the operator declaration.
  • Kullanıcı tanımlı ikili işleçler için, sol işlenen ilk parametreye karşılık gelir ve sağ işlenen işleç bildiriminin ikinci parametresine karşılık gelir.For user-defined binary operators, the left operand corresponds to the first parameter, and the right operand corresponds to the second parameter of the operator declaration.

Bağımsız değişken listelerinin çalışma süresi değerlendirmesiRun-time evaluation of argument lists

Bir işlev üye çağrısının çalışma zamanı işlemesi sırasında (dinamik aşırı yükleme çözümlemesi Için derleme zamanı denetimi), bir bağımsız değişken listesinin ifadeleri ya da değişken başvuruları, soldan sağa aşağıdaki gibi sırayla değerlendirilir:During the run-time processing of a function member invocation (Compile-time checking of dynamic overload resolution), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

  • Bir değer parametresi için bağımsız değişken ifadesi değerlendirilir ve ilgili parametre türüne örtük bir dönüştürme (örtük dönüştürmeler) gerçekleştirilir.For a value parameter, the argument expression is evaluated and an implicit conversion (Implicit conversions) to the corresponding parameter type is performed. Sonuç değeri, işlev üye çağrısında değer parametresinin başlangıç değeri olur.The resulting value becomes the initial value of the value parameter in the function member invocation.
  • Bir başvuru veya çıkış parametresi için, değişken başvurusu değerlendirilir ve sonuçta elde edilen depolama konumu, işlev üyesi çağrısında parametresi tarafından temsil edilen depolama konumu olur.For a reference or output parameter, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. Başvuru veya çıkış parametresi olarak verilen değişken başvurusu bir reference_type dizi öğesi ise, dizinin öğe türünün parametrenin türüyle aynı olduğundan emin olmak için bir çalışma zamanı denetimi yapılır.If the variable reference given as a reference or output parameter is an array element of a reference_type, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. Bu denetim başarısız olursa, bir System.ArrayTypeMismatchException oluşturulur.If this check fails, a System.ArrayTypeMismatchException is thrown.

Yöntemler, Dizin oluşturucular ve örnek oluşturucular, en sağdaki parametreleri parametre dizisi (parametre dizileri) olarak bildirebilir.Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array (Parameter arrays). Bu tür işlev üyeleri, uygulanabilir olduğu (uygulanabilir işlev üyesi) bağlı olarak kendi normal biçiminde veya genişletilmiş biçiminde çağırılır:Such function members are invoked either in their normal form or in their expanded form depending on which is applicable (Applicable function member):

  • Parametre dizisi olan bir işlev üyesi normal biçimde çağrıldığında, parametre dizisi için verilen bağımsız değişken parametre dizi türüne örtük olarak dönüştürülebilir (örtük dönüştürmeler) tek bir ifade olmalıdır.When a function member with a parameter array is invoked in its normal form, the argument given for the parameter array must be a single expression that is implicitly convertible (Implicit conversions) to the parameter array type. Bu durumda, parametre dizisi tam olarak bir değer parametresi gibi davranır.In this case, the parameter array acts precisely like a value parameter.
  • Bir parametre dizisi olan bir işlev üyesi genişletilmiş biçimde çağrıldığında, çağırma parametre dizisi için sıfır veya daha fazla Konumsal bağımsız değişkeni, her bağımsız değişkenin parametre dizisinin öğe türüne örtük olarak dönüştürülebilir bir ifade (örtük dönüştürmeler) belirtmesi gerekir.When a function member with a parameter array is invoked in its expanded form, the invocation must specify zero or more positional arguments for the parameter array, where each argument is an expression that is implicitly convertible (Implicit conversions) to the element type of the parameter array. Bu durumda, çağırma parametre dizisi türünde bağımsız değişken sayısına karşılık gelen bir örnek oluşturur, dizi örneğinin öğelerini verilen bağımsız değişken değerleriyle başlatır ve yeni oluşturulan dizi örneğini gerçek bağımsız değişken olarak kullanır.In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument.

Bir bağımsız değişken listesinin ifadeleri her zaman yazıldığı sırada değerlendirilir.The expressions of an argument list are always evaluated in the order they are written. Bu nedenle örnekThus, the example

class Test
{
    static void F(int x, int y = -1, int z = -2) {
        System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);
    }

    static void Main() {
        int i = 0;
        F(i++, i++, i++);
        F(z: i++, x: i++);
    }
}

çıktıyı üretirproduces the output

x = 0, y = 1, z = 2
x = 4, y = -1, z = 3

Dizi birlikte değişim kuralları (dizi Kovaryans), bir dizi türünün değerine A[] , bir dizi türünün bir örneğine B[] , öğesinden bir örtük başvuru dönüştürmesi sağlanmış olarak izin verir B A .The array co-variance rules (Array covariance) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. Bu kurallar nedeniyle, bir reference_type dizi öğesi başvuru veya çıkış parametresi olarak geçirildiğinde, dizinin gerçek öğe türünün parametreyle aynı olduğundan emin olmak için bir çalışma zamanı denetimi gereklidir.Because of these rules, when an array element of a reference_type is passed as a reference or output parameter, a run-time check is required to ensure that the actual element type of the array is identical to that of the parameter. ÖrnekteIn the example

class Test
{
    static void F(ref object x) {...}

    static void Main() {
        object[] a = new object[10];
        object[] b = new string[10];
        F(ref a[0]);        // Ok
        F(ref b[1]);        // ArrayTypeMismatchException
    }
}

' ın gerçek öğe türü olmadığından, öğesinin ikinci çağırma F işlemi bir oluşturulmasına neden olur System.ArrayTypeMismatchException b string object .the second invocation of F causes a System.ArrayTypeMismatchException to be thrown because the actual element type of b is string and not object.

Bir parametre dizisi olan bir işlev üyesi genişletilmiş biçimde çağrıldığında, genişletilmiş parametrelere bir dizi Başlatıcısı (dizi oluşturma ifadeleri) içeren bir dizi oluşturma ifadesi eklenirse, çağırma tam olarak işlenir.When a function member with a parameter array is invoked in its expanded form, the invocation is processed exactly as if an array creation expression with an array initializer (Array creation expressions) was inserted around the expanded parameters. Örneğin, bildirim verildiğindeFor example, given the declaration

void F(int x, int y, params object[] args);

yöntemin genişletilmiş biçimini aşağıdaki şekilde çağırmathe following invocations of the expanded form of the method

F(10, 20);
F(10, 20, 30, 40);
F(10, 20, 1, "hello", 3.0);

tam olarak karşılık gelircorrespond exactly to

F(10, 20, new object[] {});
F(10, 20, new object[] {30, 40});
F(10, 20, new object[] {1, "hello", 3.0});

Özellikle, parametre dizisi için belirtilen 0 bağımsız değişken olduğunda boş bir dizi oluşturulduğunu unutmayın.In particular, note that an empty array is created when there are zero arguments given for the parameter array.

Bağımsız değişkenler, karşılık gelen isteğe bağlı parametrelere sahip bir işlev üyesinden atlandığında, işlev üyesi bildiriminin varsayılan bağımsız değişkenleri dolaylı olarak geçirilir.When arguments are omitted from a function member with corresponding optional parameters, the default arguments of the function member declaration are implicitly passed. Bunlar her zaman sabit olduğundan, değerlendirmesi kalan bağımsız değişkenlerin değerlendirme sırasını etkilemez.Because these are always constant, their evaluation will not impact the evaluation order of the remaining arguments.

Tür çıkarımıType inference

Genel bir yöntem tür bağımsız değişkenleri belirtilmeden çağrıldığında, bir tür çıkarım işlemi çağrının tür bağımsız değişkenlerini çıkarmayı dener.When a generic method is called without specifying type arguments, a type inference process attempts to infer type arguments for the call. Tür çıkarımı varlığı, genel bir yöntemi çağırmak için daha uygun bir sözdiziminin kullanılmasına izin verir ve programcı 'nın gereksiz tür bilgilerini belirtmelerini önler.The presence of type inference allows a more convenient syntax to be used for calling a generic method, and allows the programmer to avoid specifying redundant type information. Örneğin, yöntem bildirimi verildiğinde:For example, given the method declaration:

class Chooser
{
    static Random rand = new Random();

    public static T Choose<T>(T first, T second) {
        return (rand.Next(2) == 0)? first: second;
    }
}

Chooseaçıkça bir tür bağımsız değişkeni belirtmeden yöntemi çağırmak mümkündür:it is possible to invoke the Choose method without explicitly specifying a type argument:

int i = Chooser.Choose(5, 213);                 // Calls Choose<int>

string s = Chooser.Choose("foo", "bar");        // Calls Choose<string>

Tür çıkarımı, tür bağımsız değişkenleri int ve string bağımsız değişkenlerden yöntemine göre belirlenir.Through type inference, the type arguments int and string are determined from the arguments to the method.

Tür çıkarımı, bir yöntem çağırma işleminin (Yöntem etkinleştirmeleri) bağlama zamanı işlemenin bir parçası olarak oluşur ve çağrının aşırı yükleme çözümleme adımından önce gerçekleşir.Type inference occurs as part of the binding-time processing of a method invocation (Method invocations) and takes place before the overload resolution step of the invocation. Bir yöntem çağrısında belirli bir yöntem grubu belirtildiğinde ve yöntem çağrısının bir parçası olarak hiçbir tür bağımsız değişkeni belirtilmediğinde, yöntem grubundaki her genel yönteme tür çıkarımı uygulanır.When a particular method group is specified in a method invocation, and no type arguments are specified as part of the method invocation, type inference is applied to each generic method in the method group. Tür çıkarımı başarılı olursa, sonraki aşırı yükleme çözümlemesi için bağımsız değişken türlerini belirlemede çıkartılan tür bağımsız değişkenleri kullanılır.If type inference succeeds, then the inferred type arguments are used to determine the types of arguments for subsequent overload resolution. Aşırı yükleme çözümlemesi, çağırabileceğiniz bir genel yöntem seçerse, çağırma için gerçek tür bağımsız değişkenleri olarak, çıkartılan tür bağımsız değişkenleri kullanılır.If overload resolution chooses a generic method as the one to invoke, then the inferred type arguments are used as the actual type arguments for the invocation. Belirli bir yöntemin tür çıkarımı başarısız olursa, bu yöntem aşırı yükleme çözümüne katılmaz.If type inference for a particular method fails, that method does not participate in overload resolution. , Ve içindeki çıkarım hatası, bağlama zamanı hatasına neden olmaz.The failure of type inference, in and of itself, does not cause a binding-time error. Ancak, aşırı yükleme çözümlemesi sırasında bir bağlama zamanı hatasına neden olur ve ilgili herhangi bir yöntemi bulamaz.However, it often leads to a binding-time error when overload resolution then fails to find any applicable methods.

Sağlanan bağımsız değişken sayısı yöntemdeki parametre sayısından farklıysa, çıkarımı hemen başarısız olur.If the supplied number of arguments is different than the number of parameters in the method, then inference immediately fails. Aksi takdirde, genel yöntemin aşağıdaki imzaya sahip olduğunu varsayalım:Otherwise, assume that the generic method has the following signature:

Tr M<X1,...,Xn>(T1 x1, ..., Tm xm)

Bir yöntem çağrısı ile, bu M(E1...Em) tür çıkarımı, S1...Sn X1...Xn çağrının geçerli hale gelmesi için tür parametrelerinin her biri için benzersiz tür bağımsız değişkenlerini bulmalıdır M<S1...Sn>(E1...Em) .With a method call of the form M(E1...Em) the task of type inference is to find unique type arguments S1...Sn for each of the type parameters X1...Xn so that the call M<S1...Sn>(E1...Em) becomes valid.

Çıkarımı işlemi sırasında her bir tür parametresi Xi belirli bir türe sabitlenir Si veya ilişkili bir sınır kümesiyle sabitlenemez .During the process of inference each type parameter Xi is either fixed to a particular type Si or unfixed with an associated set of bounds. Her sınırların bir türü vardır T .Each of the bounds is some type T. Başlangıçta her tür değişkeni Xi boş bir sınır kümesiyle düzeltilmedi.Initially each type variable Xi is unfixed with an empty set of bounds.

Tür çıkarımı aşamalar halinde gerçekleşir.Type inference takes place in phases. Her aşama, önceki aşamanın bulgularını temel alarak daha fazla tür değişkeni için tür bağımsız değişkenlerini çıkarması denenecek.Each phase will try to infer type arguments for more type variables based on the findings of the previous phase. İlk aşama bazı ilk dereceden sınırları yapar, ancak ikinci aşama belirli türlere tür değişkenlerini ve daha fazla sınırları düzeltir.The first phase makes some initial inferences of bounds, whereas the second phase fixes type variables to specific types and infers further bounds. İkinci aşamanın birkaç kez tekrarlanmanız gerekebilir.The second phase may have to be repeated a number of times.

Note: Tür çıkarımı yalnızca genel bir yöntem çağrıldığında değil.Note: Type inference takes place not only when a generic method is called. Yöntem gruplarının dönüştürülmesine ilişkin tür çıkarımı, Yöntem gruplarının dönüştürülmesi için tür çıkarımı ve bir ifade kümesinin en iyi ortak türünü bulma bölümünde açıklanmıştır.Type inference for conversion of method groups is described in Type inference for conversion of method groups and finding the best common type of a set of expressions is described in Finding the best common type of a set of expressions.

İlk aşamaThe first phase

Yöntem bağımsız değişkenlerinin her biri için Ei :For each of the method arguments Ei:

  • EiAnonim bir işlevse, öğesinden bir Açık parametre türü çıkarımı (Açık parametre türü) Ei``TiIf Ei is an anonymous function, an explicit parameter type inference (Explicit parameter type inferences) is made from Ei to Ti
  • Aksi halde, Ei bir tür varsa U ve xi bir değer parametresi ise, ' den daha düşük bağlantılı bir çıkarım yapılır U Ti .Otherwise, if Ei has a type U and xi is a value parameter then a lower-bound inference is made from U to Ti.
  • Aksi halde, bir Ei tür varsa U ve xi bir veya parametresi ise, ' ref out den tam çıkarımı yapılır U Ti .Otherwise, if Ei has a type U and xi is a ref or out parameter then an exact inference is made from U to Ti.
  • Aksi takdirde, bu bağımsız değişken için çıkarımı yapılmaz.Otherwise, no inference is made for this argument.

İkinci aşamaThe second phase

İkinci aşama aşağıdaki gibi ilerler:The second phase proceeds as follows:

  • Xi Hiçbir (bağımlılık) bağımlı olmayan tüm sabit olmayan tür değişkenleri Xj düzeltildi (bir Düzeltme).All unfixed type variables Xi which do not depend on (Dependence) any Xj are fixed (Fixing).
  • Böyle bir tür değişkeni yoksa, tüm sabit olmayan tür değişkenleri Xi aşağıdaki her bir bekletme için düzeltilir :If no such type variables exist, all unfixed type variables Xi are fixed for which all of the following hold:
    • Bağımlı olan en az bir tür değişkeni var Xj``XiThere is at least one type variable Xj that depends on Xi
    • Xi boş olmayan bir sınır kümesine sahipXi has a non-empty set of bounds
  • Böyle bir tür değişkeni yoksa ve hala sabit olmayan tür değişkenleri varsa, tür çıkarımı başarısız olur.If no such type variables exist and there are still unfixed type variables, type inference fails.
  • Aksi halde, daha fazla sabit olmayan tür değişkeni yoksa, tür çıkarımı başarılı olur.Otherwise, if no further unfixed type variables exist, type inference succeeds.
  • Aksi halde, Ei Ti Çıkış türlerinin (çıktı türleri) sabit olmayan tür değişkenleri içerdiği, Xj ancak Giriş türlerinin (giriş türleri) olmadığı, karşılık gelen parametre türü tüm bağımsız değişkenler için ' den ' a bir Çıkış türü çıkarımı (Çıkış türü) olarak yapılır Ei Ti .Otherwise, for all arguments Ei with corresponding parameter type Ti where the output types (Output types) contain unfixed type variables Xj but the input types (Input types) do not, an output type inference (Output type inferences) is made from Ei to Ti. İkinci aşama yinelenir.Then the second phase is repeated.

Giriş türleriInput types

EBir yöntem grubu veya örtük olarak bir adsız işlev ise ve T bir temsilci türü ya da ifade ağacı türü ise, öğesinin tüm parametre türleri T türünde giriş türleridir E T .If E is a method group or implicitly typed anonymous function and T is a delegate type or expression tree type then all the parameter types of T are input types of E with type T.

Çıkış türleriOutput types

EBir yöntem grubu veya anonim işlevse ve T bir temsilci türü ya da ifade ağacı türü ise, öğesinin dönüş türü T türünde bir Çıkış türüdür E T .If E is a method group or an anonymous function and T is a delegate type or expression tree type then the return type of T is an output type of E with type T.

Düzeyde bağımlıDependence

Türü olan bir Xi Xj Ek Tk Xj giriş türünde bir tür içeren bir bağımsız değişken varsa ve türünde bir Ek Tk Xi Çıkış türünde Ek Tk oluşursa, sabit olmayan bir tür değişkeni doğrudan sabit olmayan bir tür değişkenine bağlıdır.An unfixed type variable Xi depends directly on an unfixed type variable Xj if for some argument Ek with type Tk Xj occurs in an input type of Ek with type Tk and Xi occurs in an output type of Ek with type Tk.

Xjbağlı Xi Eğer Xj doğrudan açık ya da bağlı ise, öğesine bağlıdır Xi Xi Xk Xk Xj .Xj depends on Xi if Xj depends directly on Xi or if Xi depends directly on Xk and Xk depends on Xj. Bu nedenle "bağlı olan", geçişli ancak yansımalı olmayan "açık" kapanışı değildir.Thus "depends on" is the transitive but not reflexive closure of "depends directly on".

Çıkış türü ındaOutput type inferences

Bir ifadeden Çıkış türü çıkarımı E aşağıdaki şekilde bir türe yapılır T :An output type inference is made from an expression E to a type T in the following way:

  • , E Çıkarılan dönüş türü U (çıkartılan dönüş türü) olan bir anonim işlevse ve T dönüş türü olan bir temsilci türü ya da ifade ağacı türü ise Tb , ' den ' e göre daha düşük bağlantılı bir çıkarım (alt sınır) yapılır U Tb .If E is an anonymous function with inferred return type U (Inferred return type) and T is a delegate type or expression tree type with return type Tb, then a lower-bound inference (Lower-bound inferences) is made from U to Tb.
  • Aksi takdirde, E bir yöntem grubudur ve T parametre türleri ve dönüş türü olan bir temsilci türü ya da ifade ağacı türü ise T1...Tk Tb ve türleri ile aşırı yükleme çözümlemesi, E T1...Tk dönüş türüne sahip tek bir yöntem alıyorsa U , ' den ' e daha düşük bağlantılı bir çıkarım yapılır U Tb .Otherwise, if E is a method group and T is a delegate type or expression tree type with parameter types T1...Tk and return type Tb, and overload resolution of E with the types T1...Tk yields a single method with return type U, then a lower-bound inference is made from U to Tb.
  • Aksi halde, E türünde bir ifadesiyse U , ' den ' e daha düşük bağlantılı bir çıkarım yapılır U T .Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.
  • Aksi takdirde, hiçbir Inse yapılmaz.Otherwise, no inferences are made.

Açık parametre türüExplicit parameter type inferences

Bir ifadeden bir türe Açık parametre türü çıkarımı E T aşağıdaki şekilde yapılır:An explicit parameter type inference is made from an expression E to a type T in the following way:

  • EParametre türleri ile açık olarak belirlenmiş bir anonim işlev ise U1...Uk ve T bir temsilci türü ya da parametre türleri olan ifade ağacı türü ise, V1...Vk her Ui bir tam çıkarım (tam) için Ui , karşılık gelen öğesine yapılır Vi .If E is an explicitly typed anonymous function with parameter types U1...Uk and T is a delegate type or expression tree type with parameter types V1...Vk then for each Ui an exact inference (Exact inferences) is made from Ui to the corresponding Vi.

Tam ındaExact inferences

Türden bir türden tam bir çıkarım U V aşağıdaki şekilde yapılır:An exact inference from a type U to a type V is made as follows:

  • VBunlardan biri ise, Xi U için tam sınırlara eklenir Xi .If V is one of the unfixed Xi then U is added to the set of exact bounds for Xi.

  • Aksi takdirde, ayarlar V1...Vk ve U1...Uk aşağıdaki durumlardan herhangi biri uygulanabilir olup olmadığını denetleyerek belirlenir:Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

    • V bir dizi türüdür V1[...] ve U U1[...] aynı derecenin dizi türüdürV is an array type V1[...] and U is an array type U1[...] of the same rank
    • V tür V1? ve U türdür U1?V is the type V1? and U is the type U1?
    • V oluşturulmuş bir tür C<V1...Vk> ve U oluşturulmuş bir tür C<U1...Uk>V is a constructed type C<V1...Vk>and U is a constructed type C<U1...Uk>

    Bu durumlardan herhangi biri uygunsa, her birinden karşılık gelen kesin bir çıkarım yapılır Ui Vi .If any of these cases apply then an exact inference is made from each Ui to the corresponding Vi.

  • Aksi takdirde hiçbir Inse yapılmaz.Otherwise no inferences are made.

Alt sınırLower-bound inferences

Türden bir türe daha düşük bağlantılı bir çıkarım U V aşağıdaki şekilde yapılır:A lower-bound inference from a type U to a type V is made as follows:

  • Değilse V , daha Xi sonra U için alt sınırlar kümesine eklenir Xi .If V is one of the unfixed Xi then U is added to the set of lower bounds for Xi.

  • Aksi takdirde, V türüdür ve tür ise, ' V1? U U1? den daha düşük bir sınır çıkarımı yapılır U1 V1 .Otherwise, if V is the type V1?and U is the type U1? then a lower bound inference is made from U1 to V1.

  • Aksi takdirde, ayarlar U1...Uk ve V1...Vk aşağıdaki durumlardan herhangi biri uygulanabilir olup olmadığını denetleyerek belirlenir:Otherwise, sets U1...Uk and V1...Vk are determined by checking if any of the following cases apply:

    • V bir dizi türüdür V1[...] ve U aynı derecenin bir dizi türü U1[...] (veya geçerli temel türü olan bir tür parametresi U1[...] )V is an array type V1[...] and U is an array type U1[...] (or a type parameter whose effective base type is U1[...]) of the same rank

    • V``IEnumerable<V1>, veya, tek ICollection<V1> IList<V1> boyutlu bir U dizi türüdür U1[] (veya geçerli temel türü olan bir tür parametresidir U1[] )V is one of IEnumerable<V1>, ICollection<V1> or IList<V1> and U is a one-dimensional array type U1[](or a type parameter whose effective base type is U1[])

    • V oluşturulmuş bir sınıf, yapı, arabirim veya temsilci türüdür C<V1...Vk> ve C<U1...Uk> U (ya da U bir tür parametresi ise, etkin taban sınıfı veya etkin arabirim kümesinin herhangi bir üyesi) ile özdeş, devralır (doğrudan veya dolaylı) veya uygular (doğrudan veya dolaylı) C<U1...Uk> .V is a constructed class, struct, interface or delegate type C<V1...Vk> and there is a unique type C<U1...Uk> such that U (or, if U is a type parameter, its effective base class or any member of its effective interface set) is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) C<U1...Uk>.

      ("Benzersizlik" kısıtlaması, büyük/küçük harf C<T> {} class U: C<X>, C<Y> {} olmasından dolayı ' den itibaren olduğu zaman bir çıkarımı yapılmadığı anlamına gelir U C<T> U1 X Y .)(The "uniqueness" restriction means that in the case interface C<T> {} class U: C<X>, C<Y> {}, then no inference is made when inferring from U to C<T> because U1 could be X or Y.)

    Bu durumlardan herhangi biri uygunsa, her biri Ui aşağıdaki gibi bir çıkarım yapılır Vi :If any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

    • UiBir başvuru türü olarak bilinmiyorsa, kesin bir çıkarım yapılırIf Ui is not known to be a reference type then an exact inference is made
    • Aksi halde, U bir dizi türü ise, alt sınır çıkarımı yapılırOtherwise, if U is an array type then a lower-bound inference is made
    • Aksi halde, V ise C<V1...Vk> çıkarımı ı-TH türü parametresine bağlıdır C :Otherwise, if V is C<V1...Vk> then inference depends on the i-th type parameter of C:
      • Daha fazla değişken ise, alt sınır çıkarımı yapılır.If it is covariant then a lower-bound inference is made.
      • Değişken karşıtı ise, üst sınır çıkarımı yapılır.If it is contravariant then an upper-bound inference is made.
      • Sabit ise, kesin bir çıkarım yapılır.If it is invariant then an exact inference is made.
  • Aksi takdirde, hiçbir Inse yapılmaz.Otherwise, no inferences are made.

Üst sınırUpper-bound inferences

Türden bir türe üst sınır çıkarımı U V aşağıdaki gibi yapılır:An upper-bound inference from a type U to a type V is made as follows:

  • VBunlardan biri ise Xi U üst sınır kümesine eklenir Xi .If V is one of the unfixed Xi then U is added to the set of upper bounds for Xi.

  • Aksi takdirde, ayarlar V1...Vk ve U1...Uk aşağıdaki durumlardan herhangi biri uygulanabilir olup olmadığını denetleyerek belirlenir:Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

    • U bir dizi türüdür U1[...] ve V V1[...] aynı derecenin dizi türüdürU is an array type U1[...] and V is an array type V1[...] of the same rank

    • U``IEnumerable<Ue>, ICollection<Ue> ya da IList<Ue> V tek boyutlu bir dizi türüdürVe[]U is one of IEnumerable<Ue>, ICollection<Ue> or IList<Ue> and V is a one-dimensional array type Ve[]

    • U tür U1? ve V türdür V1?U is the type U1? and V is the type V1?

    • U oluşturulan sınıf, yapı, arabirim veya temsilci türü C<U1...Uk> ve ile V özdeş olan, devralınan (doğrudan veya dolaylı) veya benzersiz bir tür (doğrudan veya dolaylı olarak) uygulayan bir sınıf, yapı, arabirim veya temsilci türü C<V1...Vk>U is constructed class, struct, interface or delegate type C<U1...Uk> and V is a class, struct, interface or delegate type which is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) a unique type C<V1...Vk>

      ("Benzersizlik" kısıtlaması interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{} , varsa, ' den ' a kadar bir çıkarımı yapılmayacağı anlamına gelir C<U1> V<Q> .(The "uniqueness" restriction means that if we have interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{}, then no inference is made when inferring from C<U1> to V<Q>. Inor, ' den veya ' a uygulanmaz U1 X<Q> Y<Q> .)Inferences are not made from U1 to either X<Q> or Y<Q>.)

    Bu durumlardan herhangi biri uygunsa, her biri Ui aşağıdaki gibi bir çıkarım yapılır Vi :If any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

    • UiBir başvuru türü olarak bilinmiyorsa, kesin bir çıkarım yapılırIf Ui is not known to be a reference type then an exact inference is made
    • Aksi halde, V bir dizi türü ise, üst sınır çıkarımı yapılırOtherwise, if V is an array type then an upper-bound inference is made
    • Aksi halde, U ise C<U1...Uk> çıkarımı ı-TH türü parametresine bağlıdır C :Otherwise, if U is C<U1...Uk> then inference depends on the i-th type parameter of C:
      • Covaryant ise, üst sınır çıkarımı yapılır.If it is covariant then an upper-bound inference is made.
      • Değişken karşıtı ise, alt sınır çıkarımı yapılır.If it is contravariant then a lower-bound inference is made.
      • Sabit ise, kesin bir çıkarım yapılır.If it is invariant then an exact inference is made.
  • Aksi takdirde, hiçbir Inse yapılmaz.Otherwise, no inferences are made.

öğesini düzeltmeFixing

Bir dizi sınırı olan sabit olmayan bir tür değişkeni Xi aşağıdaki gibi düzeltilir :An unfixed type variable Xi with a set of bounds is fixed as follows:

  • Aday türleri kümesi, Uj için sınırları kümesindeki tüm türlerin kümesi olarak başlatılır Xi .The set of candidate types Uj starts out as the set of all types in the set of bounds for Xi.
  • Bundan sonra her bir bağı sırayla inceleyeceğiz Xi : U aynı olmayan tüm türlerin her bir tam sınırı için Xi Uj U aday kümesinden kaldırılır.We then examine each bound for Xi in turn: For each exact bound U of Xi all types Uj which are not identical to U are removed from the candidate set. U Xi Uj İçinden örtük dönüştürme olmayan tüm türlerin alt sınırı için U aday kümesinden kaldırılır.For each lower bound U of Xi all types Uj to which there is not an implicit conversion from U are removed from the candidate set. U Xi Örtülü dönüştürme olmayan tüm türlerin üst sınırı için Uj U aday kümesinden kaldırılır.For each upper bound U of Xi all types Uj from which there is not an implicit conversion to U are removed from the candidate set.
  • Kalan aday türleri arasında, Uj V tüm diğer aday türlerine örtük bir dönüştürme olan benzersiz bir tür vardır ve sonra Xi düzeltilir V .If among the remaining candidate types Uj there is a unique type V from which there is an implicit conversion to all the other candidate types, then Xi is fixed to V.
  • Aksi takdirde tür çıkarımı başarısız olur.Otherwise, type inference fails.

Çıkarılan dönüş türüInferred return type

Anonim bir işlevin çıkarılan dönüş türü, F tür çıkarımı ve aşırı yükleme çözümlemesi sırasında kullanılır.The inferred return type of an anonymous function F is used during type inference and overload resolution. Çıkarılan dönüş türü yalnızca, açıkça verildiği, anonim bir işlev dönüştürme yoluyla sağlanan veya kapsayan genel yöntem çağrısında çıkarım sırasında çıkarılan bir anonim işlev için belirlenebilir.The inferred return type can only be determined for an anonymous function where all parameter types are known, either because they are explicitly given, provided through an anonymous function conversion or inferred during type inference on an enclosing generic method invocation.

Çıkarılan sonuç türü aşağıdaki şekilde belirlenir:The inferred result type is determined as follows:

  • Gövdesi F türü olan bir ifade ise, ' nin çıkarılan sonuç türü F Bu ifadenin türüdür.If the body of F is an expression that has a type, then the inferred result type of F is the type of that expression.
  • ' In gövdesi F bir blok ise ve blok deyimlerindeki ifadelerin kümesi return en iyi ortak türe sahiptir T (bir ifade kümesinin en iyi ortak türünü bulmayla) ve çıkarılan sonuç türü F olur T .If the body of F is a block and the set of expressions in the block's return statements has a best common type T (Finding the best common type of a set of expressions), then the inferred result type of F is T.
  • Aksi takdirde, için bir sonuç türü çıkarsanamıyor F .Otherwise, a result type cannot be inferred for F.

Çıkarılan dönüş türü aşağıdaki şekilde belirlenir:The inferred return type is determined as follows:

  • FZaman uyumsuz ise ve gövdesi F Nothing (ifade sınıflandırmaları) olarak sınıflandırılmış bir ifade ya da hiçbir dönüş deyiminin ifadesi olmadığı bir deyim bloğu ise, çıkarılan dönüş türüSystem.Threading.Tasks.TaskIf F is async and the body of F is either an expression classified as nothing (Expression classifications), or a statement block where no return statements have expressions, the inferred return type is System.Threading.Tasks.Task
  • FZaman uyumsuz ise ve ortaya çıkarılan bir sonuç türü varsa T , çıkarılan dönüş türü olur System.Threading.Tasks.Task<T> .If F is async and has an inferred result type T, the inferred return type is System.Threading.Tasks.Task<T>.
  • FZaman uyumsuz ve ortaya çıkarılan bir sonuç türüne sahipse T , çıkarılan dönüş türü olur T .If F is non-async and has an inferred result type T, the inferred return type is T.
  • Aksi takdirde, için bir dönüş türü çıkarsanamıyor F .Otherwise a return type cannot be inferred for F.

Anonim işlevler içeren tür çıkarımı örneği olarak, Select sınıfında belirtilen genişletme yöntemini göz önünde bulundurun System.Linq.Enumerable :As an example of type inference involving anonymous functions, consider the Select extension method declared in the System.Linq.Enumerable class:

namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable<TResult> Select<TSource,TResult>(
            this IEnumerable<TSource> source,
            Func<TSource,TResult> selector)
        {
            foreach (TSource element in source) yield return selector(element);
        }
    }
}

System.LinqAd alanının bir yan tümcesiyle içeri aktarıldığına using ve türünde bir özelliği olan bir sınıfın verilme varsayılırsa Customer Name string , Select Yöntem bir müşteri listesinin adlarını seçmek için kullanılabilir:Assuming the System.Linq namespace was imported with a using clause, and given a class Customer with a Name property of type string, the Select method can be used to select the names of a list of customers:

List<Customer> customers = GetCustomerList();
IEnumerable<string> names = customers.Select(c => c.Name);

Öğesinin genişletme yöntemi çağrısı (genişletme yöntemi etkinleştirmeleri), Select statik bir yöntem çağrısına yapılan çağrıyı yeniden yazarak işlenir:The extension method invocation (Extension method invocations) of Select is processed by rewriting the invocation to a static method invocation:

IEnumerable<string> names = Enumerable.Select(customers, c => c.Name);

Tür bağımsız değişkenleri açıkça belirtilmediği için tür çıkarımı tür bağımsız değişkenlerini çıkarsanacak şekilde kullanılır.Since type arguments were not explicitly specified, type inference is used to infer the type arguments. İlk olarak, customers bağımsız değişken parametresi ile ilgilidir ve bu source parametre, olduğu gibi T olur Customer .First, the customers argument is related to the source parameter, inferring T to be Customer. Daha sonra, yukarıda açıklanan anonim işlev türü çıkarımı işlemini kullanarak c tür verilir Customer ve ifade, parametrenin dönüş türüyle ilişkili olur ve bu da, c.Name selector S olması gerekir string .Then, using the anonymous function type inference process described above, c is given type Customer, and the expression c.Name is related to the return type of the selector parameter, inferring S to be string. Bu nedenle, çağırma şu şekilde eşdeğerdirThus, the invocation is equivalent to

Sequence.Select<Customer,string>(customers, (Customer c) => c.Name)

ve sonuç türündedir IEnumerable<string> .and the result is of type IEnumerable<string>.

Aşağıdaki örnek, anonim işlev türü çıkarımını genel yöntem çağrısında bağımsız değişkenler arasında "Flow" öğesine nasıl izin verdiğini gösterir.The following example demonstrates how anonymous function type inference allows type information to "flow" between arguments in a generic method invocation. Yöntem verildi:Given the method:

static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2) {
    return f2(f1(value));
}

Çağırma için tür çıkarımı:Type inference for the invocation:

double seconds = F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds);

Şu şekilde devam eder: Ilk olarak bağımsız değişken, parametresi ile ilgilidir ve bu "1:15:30" value parametrenin X olması gerekir string .proceeds as follows: First, the argument "1:15:30" is related to the value parameter, inferring X to be string. Ardından, birinci anonim işlevin parametresine, s Çıkarsanan tür verilir string ve ifade, dönüş türü ile ilgilidir ve bu da TimeSpan.Parse(s) f1 Y olur System.TimeSpan .Then, the parameter of the first anonymous function, s, is given the inferred type string, and the expression TimeSpan.Parse(s) is related to the return type of f1, inferring Y to be System.TimeSpan. Son olarak, ikinci adsız işlevin parametresi, t Çıkarsanan tür System.TimeSpan olarak verilir ve ifade, dönüş türü ile ilgilidir ve bu da t.TotalSeconds f2 Z olur double .Finally, the parameter of the second anonymous function, t, is given the inferred type System.TimeSpan, and the expression t.TotalSeconds is related to the return type of f2, inferring Z to be double. Bu nedenle, çağrının sonucu türündedir double .Thus, the result of the invocation is of type double.

Yöntem gruplarının dönüştürülmesi için tür çıkarımıType inference for conversion of method groups

Genel yöntemlerin çağrılarına benzer şekilde, M genel bir yöntem içeren bir yöntem grubu verilen temsilci türüne D (Yöntem grubu dönüştürmeleri) dönüştürüldüğünde tür çıkarımı da uygulanmalıdır.Similar to calls of generic methods, type inference must also be applied when a method group M containing a generic method is converted to a given delegate type D (Method group conversions). Verilen YöntemGiven a method

Tr M<X1...Xn>(T1 x1 ... Tm xm)

ve M temsilci türüne atanmakta olan Yöntem grubu tür D çıkarımı, ifadenin tür bağımsız değişkenlerini bulmaktadır, S1...Sn Bu nedenle:and the method group M being assigned to the delegate type D the task of type inference is to find type arguments S1...Sn so that the expression:

M<S1...Sn>

ile uyumlu (temsilci bildirimleri) olur D .becomes compatible (Delegate declarations) with D.

Genel yöntem çağrılarının tür çıkarımı algoritmasından farklı olarak, bu durumda yalnızca bağımsız değişken türleri vardır, hiçbir bağımsız değişken ifadesi yoktur.Unlike the type inference algorithm for generic method calls, in this case there are only argument types, no argument expressions. Özellikle, anonim işlev yoktur ve bu nedenle birden çok çıkarım aşaması gerekmez.In particular, there are no anonymous functions and hence no need for multiple phases of inference.

Bunun yerine, tümü Xi düzeltilmez olarak değerlendirilir ve her bağımsız değişken türünden öğesine karşılık gelen parametre türüne alt sınır çıkarımı yapılır Uj D Tj M .Instead, all Xi are considered unfixed, and a lower-bound inference is made from each argument type Uj of D to the corresponding parameter type Tj of M. XiHiçbir sınır bulunmazsa, tür çıkarımı başarısız olur.If for any of the Xi no bounds were found, type inference fails. Aksi takdirde, hepsi Xi tür çıkarımı sonucu olan karşılık gelen öğesine sabitlenmiştir Si .Otherwise, all Xi are fixed to corresponding Si, which are the result of type inference.

Bir ifade kümesinin en iyi ortak türünü bulmaFinding the best common type of a set of expressions

Bazı durumlarda, bir dizi ifade için ortak bir türün çıkarsanması gerekir.In some cases, a common type needs to be inferred for a set of expressions. Özellikle, örtük olarak yazılan dizilerin öğe türleri ve blok gövdeleri olan anonim işlevlerin dönüş türleri bu şekilde bulunur.In particular, the element types of implicitly typed arrays and the return types of anonymous functions with block bodies are found in this way.

Intuicanlı, E1...Em Bu çıkarım bir yöntemi çağırmak için eşdeğer olmalıdırIntuitively, given a set of expressions E1...Em this inference should be equivalent to calling a method

Tr M<X>(X x1 ... X xm)

Eias bağımsız değişkenleriyle.with the Ei as arguments.

Daha kesin olarak, çıkarım, sabit olmayan bir tür değişkeniyle başlar X .More precisely, the inference starts out with an unfixed type variable X. Çıktı türü , sonrasında her birinden yapılır Ei X .Output type inferences are then made from each Ei to X. Son olarak X , sabittir ve başarılıysa, sonuçta elde edilen tür, S ifadeler için en iyi ortak türdür.Finally, X is fixed and, if successful, the resulting type S is the resulting best common type for the expressions. Böyle bir S mevcut değilse, ifadelerin en iyi ortak türü yoktur.If no such S exists, the expressions have no best common type.

Aşırı yükleme çözümüOverload resolution

Aşırı yükleme çözümlemesi, verilen bağımsız değişken listesini ve aday işlev üyelerini çağırmak için en iyi işlev üyesini seçmeye yönelik bir bağlama zamanı mekanizmasıdır.Overload resolution is a binding-time mechanism for selecting the best function member to invoke given an argument list and a set of candidate function members. Aşırı yükleme çözümlemesi C# içindeki aşağıdaki ayrı bağlamlarda çağrılacak işlev üyesini seçer:Overload resolution selects the function member to invoke in the following distinct contexts within C#:

Bu bağlamların her biri, yukarıda listelenen bölümlerde ayrıntılı olarak açıklandığı gibi aday işlev üyeleri kümesini ve bağımsız değişkenlerin listesini kendi benzersiz şeklinde tanımlar.Each of these contexts defines the set of candidate function members and the list of arguments in its own unique way, as described in detail in the sections listed above. Örneğin, bir yöntem çağrısı için aday kümesi override (üye arama) olarak işaretlenmiş yöntemleri içermez ve türetilmiş bir sınıftaki herhangi bir yöntem geçerliyse (Yöntem etkinleştirmeleri) bir temel sınıftaki Yöntemler aday değildir.For example, the set of candidates for a method invocation does not include methods marked override (Member lookup), and methods in a base class are not candidates if any method in a derived class is applicable (Method invocations).

Aday işlev üyeleri ve bağımsız değişken listesi tanımlandıktan sonra, en iyi işlev üyesinin seçimi her durumda aynıdır:Once the candidate function members and the argument list have been identified, the selection of the best function member is the same in all cases:

  • Uygulanabilir aday işlev üyeleri kümesi verildiğinde, bu küme içindeki en iyi işlev üyesi bulunur.Given the set of applicable candidate function members, the best function member in that set is located. Küme yalnızca bir işlev üyesi içeriyorsa, bu işlev üyesi en iyi işlev üyesidir.If the set contains only one function member, then that function member is the best function member. Aksi halde, en iyi işlev üyesi, her bir işlev üyesinin daha iyi işlev üyesindeolan kuralları kullanarak diğer tüm işlev üyeleriyle karşılaştırıldığı belirtilen bağımsız değişken listesine göre daha iyi olan bir işlev üyesidir.Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in Better function member. Tüm diğer işlev üyelerinden daha iyi olan tam olarak bir işlev üyesi yoksa, işlev üye çağrısı belirsizdir ve bir bağlama zamanı hatası oluşur.If there is not exactly one function member that is better than all other function members, then the function member invocation is ambiguous and a binding-time error occurs.

Aşağıdaki bölümlerde, koşulların *geçerli işlev üyesi _ ve _ daha iyi işlev üyesi * tam anlamları tanımlanacaktır.The following sections define the exact meanings of the terms applicable function member _ and _better function member**.

Geçerli işlev üyesiApplicable function member

Bir işlev üyesi, aşağıdakilerin tümü doğru olduğunda bir bağımsız değişken listesine göre geçerli bir işlev üyesi olarak kabul edilir A :A function member is said to be an applicable function member with respect to an argument list A when all of the following are true:

  • İçindeki her bağımsız değişken, A karşılık gelen parametrelerdeaçıklandığı gibi işlev üye bildirimindeki bir parametreye karşılık gelir ve hiçbir bağımsız değişkenin karşılık geldiği parametre isteğe bağlı bir parametredir.Each argument in A corresponds to a parameter in the function member declaration as described in Corresponding parameters, and any parameter to which no argument corresponds is an optional parameter.
  • İçindeki her bağımsız değişken için A , bağımsız değişkenin (örn., veya) parametre geçirme modu, ref out karşılık gelen parametrenin parametre geçirme moduyla aynıdır veFor each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is identical to the parameter passing mode of the corresponding parameter, and
    • bir değer parametresi veya bir parametre dizisi için, bağımsız değişkenden karşılık gelen parametrenin türüne örtük bir dönüştürme (örtük dönüştürmeler) var veyafor a value parameter or a parameter array, an implicit conversion (Implicit conversions) exists from the argument to the type of the corresponding parameter, or
    • bir ref veya out parametresi için bağımsız değişkenin türü karşılık gelen parametrenin türüyle aynıdır.for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. All, bir ref veya out parametresi geçilen bağımsız değişken için bir diğer addır.After all, a ref or out parameter is an alias for the argument passed.

Bir parametre dizisi içeren bir işlev üyesi için, işlev üyesi yukarıdaki kurallarla geçerliyse, bu, *normal form _ ' de geçerli olacaktır.For a function member that includes a parameter array, if the function member is applicable by the above rules, it is said to be applicable in its *normal form _. Bir parametre dizisi içeren bir işlev üyesi normal biçiminde geçerli değilse, işlev üyesi bunun yerine _ genişletilmiş form * içinde uygulanabilir.If a function member that includes a parameter array is not applicable in its normal form, the function member may instead be applicable in its _*expanded form**:

  • Genişletilmiş form, işlev üyesi bildirimindeki parametre dizisinin parametre dizisinin öğe türünün sıfır veya daha fazla değer parametresiyle değiştirilerek oluşturulur ve bağımsız değişken listesindeki bağımsız değişkenlerin sayısı, A toplam parametre sayısıyla eşleşir.The expanded form is constructed by replacing the parameter array in the function member declaration with zero or more value parameters of the element type of the parameter array such that the number of arguments in the argument list A matches the total number of parameters. Aİşlev üyesi bildirimindeki sabit parametrelerin sayısından daha az bağımsız değişken varsa, işlev üyesinin genişletilmiş biçimi oluşturulamaz ve bu nedenle geçerli değildir.If A has fewer arguments than the number of fixed parameters in the function member declaration, the expanded form of the function member cannot be constructed and is thus not applicable.
  • Aksi takdirde genişletilmiş form, bağımsız değişkeninin parametre geçirme modundaki her bir bağımsız değişken için A karşılık gelen parametrenin parametre geçirme moduyla özdeş olduğunda uygulanabilir.Otherwise, the expanded form is applicable if for each argument in A the parameter passing mode of the argument is identical to the parameter passing mode of the corresponding parameter, and
    • sabit bir değer parametresi veya genişletme tarafından oluşturulan bir değer parametresi için, bağımsız değişkenin türünden, karşılık gelen parametrenin türüne örtük bir dönüştürme (örtük dönüştürmeler) vardır veyafor a fixed value parameter or a value parameter created by the expansion, an implicit conversion (Implicit conversions) exists from the type of the argument to the type of the corresponding parameter, or
    • bir ref veya out parametresi için bağımsız değişkenin türü karşılık gelen parametrenin türüyle aynıdır.for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter.

Daha iyi işlev üyesiBetter function member

Daha iyi işlev üyesini belirleme amaçları doğrultusunda, yalnızca bağımsız değişken ifadelerinin orijinal bağımsız değişken listesinde göründükleri sırada kendilerini içeren bir aşağı açılan bağımsız değişken listesi oluşturulur.For the purposes of determining the better function member, a stripped-down argument list A is constructed containing just the argument expressions themselves in the order they appear in the original argument list.

Aday işlev üyelerinin her biri için parametre listeleri aşağıdaki şekilde oluşturulur:Parameter lists for each of the candidate function members are constructed in the following way:

  • İşlev üyesi yalnızca genişletilmiş biçimde uygulanabiliyorsa genişletilmiş form kullanılır.The expanded form is used if the function member was applicable only in the expanded form.
  • Karşılık gelen bağımsız değişken içermeyen isteğe bağlı parametreler parametre listesinden kaldırılırOptional parameters with no corresponding arguments are removed from the parameter list
  • Parametreler, bağımsız değişken listesindeki ilgili bağımsız değişkenle aynı konumda gerçekleşmeleri için yeniden sıralanmaz.The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list.

ABağımsız değişken ifadeleri kümesi {E1, E2, ..., En} ve iki uygulanabilir işlev üyesi ve Mp Mq parametre türleriyle {P1, P2, ..., Pn} {Q1, Q2, ..., Qn} Mp Mq birlikte bir bağımsız değişken listesi verildiğinde,Given an argument list A with a set of argument expressions {E1, E2, ..., En} and two applicable function members Mp and Mq with parameter types {P1, P2, ..., Pn} and {Q1, Q2, ..., Qn}, Mp is defined to be a better function member than Mq if

  • Her bağımsız değişken için, öğesinden öğesine örtük dönüştürme, Ex Qx ' dan ' a örtülü dönüşümden daha iyi değildir Ex Px vefor each argument, the implicit conversion from Ex to Qx is not better than the implicit conversion from Ex to Px, and
  • en az bir bağımsız değişken için, ' dan ' a dönüştürme Ex Px işleminden daha iyidir Ex Qx .for at least one argument, the conversion from Ex to Px is better than the conversion from Ex to Qx.

Bu değerlendirmeyi gerçekleştirirken, Mp veya Mq genişletilmiş biçiminde geçerliyse, Px ya da Qx parametre listesinin genişletilmiş biçimindeki bir parametreye başvurur.When performing this evaluation, if Mp or Mq is applicable in its expanded form, then Px or Qx refers to a parameter in the expanded form of the parameter list.

Parametre türü dizileri  {P1, P2, ..., Pn} ve eşdeğer olması durumunda {Q1, Q2, ..., Qn} (her biri Pi karşılık gelen bir kimlik dönüştürmesi varsa Qi ), daha iyi işlev üyesini belirleyebilmek için aşağıdaki bağlama kuralları uygulanır.In case the parameter type sequences {P1, P2, ..., Pn} and {Q1, Q2, ..., Qn} are equivalent (i.e. each Pi has an identity conversion to the corresponding Qi), the following tie-breaking rules are applied, in order, to determine the better function member.

  • MpGenel olmayan bir yöntem ise ve genel bir Mq yöntemse, daha Mp iyidir Mq .If Mp is a non-generic method and Mq is a generic method, then Mp is better than Mq.
  • Aksi takdirde, Mp normal biçimde uygulanabilir ve Mq bir params dizi içeriyorsa ve yalnızca genişletilmiş biçimde geçerliyse, daha Mp iyidir Mq .Otherwise, if Mp is applicable in its normal form and Mq has a params array and is applicable only in its expanded form, then Mp is better than Mq.
  • Aksi takdirde, Mp öğesinden daha fazla tanımlanmış parametre varsa Mq , daha Mp iyidir Mq .Otherwise, if Mp has more declared parameters than Mq, then Mp is better than Mq. Her iki yöntem de params diziler içeriyorsa ve yalnızca genişletilmiş formlarında uygulanabildiğinde bu durum oluşabilir.This can occur if both methods have params arrays and are applicable only in their expanded forms.
  • Aksi halde, öğesinin tüm parametreleri Mp karşılık gelen bir bağımsız değişkene sahip ise, varsayılan bağımsız değişkenlerin yerine en az bir isteğe bağlı parametre yerine Mq geçilmesine gerek olması gerekir Mp Mq .Otherwise if all parameters of Mp have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in Mq then Mp is better than Mq.
  • Aksi halde, Mp daha fazla özel parametre türü varsa Mq , daha Mp iyidir Mq .Otherwise, if Mp has more specific parameter types than Mq, then Mp is better than Mq. {R1, R2, ..., Rn} {S1, S2, ..., Sn} Ve öğesinin örneklenmiş ve genişletilmemiş parametre türlerini sağlar ve temsil edin Mp Mq .Let {R1, R2, ..., Rn} and {S1, S2, ..., Sn} represent the uninstantiated and unexpanded parameter types of Mp and Mq. Mpparametre türleri, Mq her bir parametre için ' den daha belirgin Rx değildir Sx ve en az bir parametre için Rx şundan daha belirgin değildir Sx :Mp's parameter types are more specific than Mq's if, for each parameter, Rx is not less specific than Sx, and, for at least one parameter, Rx is more specific than Sx:
    • Tür parametresi, tür olmayan bir parametreden daha az özgüdür.A type parameter is less specific than a non-type parameter.
    • Yinelemeli olarak, oluşturulmuş bir tür, en az bir tür bağımsız değişkeni daha büyükse ve hiçbir tür bağımsız değişkeni diğer bir tür bağımsız değişkeniyle daha az özel değilse, oluşturulmuş bir tür farklı oluşturulmuş türden (aynı sayıda tür bağımsız değişkenle) daha özgüdür.Recursively, a constructed type is more specific than another constructed type (with the same number of type arguments) if at least one type argument is more specific and no type argument is less specific than the corresponding type argument in the other.
    • Bir dizi türü, birincinin öğe türü ikincisinin öğe türünden daha belirgin ise, başka bir dizi türünden (aynı sayıda boyut ile) daha özgüdür.An array type is more specific than another array type (with the same number of dimensions) if the element type of the first is more specific than the element type of the second.
  • Aksi takdirde, bir üye yükseltilmemiş olmayan bir işleçtir ve diğeri bir yükseltilmemiş işleçse, yükseltilmemiş olmayan bir tane daha iyidir.Otherwise if one member is a non-lifted operator and the other is a lifted operator, the non-lifted one is better.
  • Aksi halde, hiçbir işlev üyesi daha iyidir.Otherwise, neither function member is better.

Deyimden daha iyi dönüştürmeBetter conversion from expression

C1Bir ifadeden bir türe dönüştüren örtük bir dönüştürme E T1 ve bir ifadeden bir türe dönüştüren örtük bir dönüştürme C2 E T2 C1 belirtildiğinde, tam olarak eşleşmeyen C2 E T2 ve en az bir tane olan bir dönüştürme daha iyi bir dönüştürmedir:Given an implicit conversion C1 that converts from an expression E to a type T1, and an implicit conversion C2 that converts from an expression E to a type T2, C1 is a better conversion than C2 if E does not exactly match T2 and at least one of the following holds:

Tam eşleştirme IfadesiExactly matching Expression

Bir ifade E ve bir tür verildiğinde T , aşağıdakilerden E T biri varsa, tam olarak eşleşir:Given an expression E and a type T, E exactly matches T if one of the following holds:

  • Ebir türe sahiptir S ve ' den ' a bir kimlik dönüştürmesi vardır S``TE has a type S, and an identity conversion exists from S to T
  • E anonim bir işlevdir, T bir temsilci türü D veya bir ifade ağacı türü ve aşağıdakilerden biri olabilir Expression<D> :E is an anonymous function, T is either a delegate type D or an expression tree type Expression<D> and one of the following holds:
    • X E ' In parametre listesi bağlamında D (çıkarılan dönüş türü) için gösterilen bir dönüş türü vardır ve öğesinden bir kimlik dönüştürme X``DAn inferred return type X exists for E in the context of the parameter list of D (Inferred return type), and an identity conversion exists from X to the return type of D
    • EZaman uyumsuz değil ve D bir dönüş türüne sahip ya da Y E zaman uyumsuz ve D bir dönüş türüne sahip ve aşağıdakilerden Task<Y> biri tutuyor:Either E is non-async and D has a return type Y or E is async and D has a return type Task<Y>, and one of the following holds:
      • Gövdesi E tam olarak eşleşen bir ifadedir YThe body of E is an expression that exactly matches Y
      • Gövdesi, E her dönüş deyiminin tam olarak eşleşen bir ifade döndürdüğü bir deyim bloğu YThe body of E is a statement block where every return statement returns an expression that exactly matches Y

Daha iyi dönüştürme hedefiBetter conversion target

İki farklı tür T1 ve T2 , ' T1 T2 den örtük dönüştürme yoksa T2 T1 ve aşağıdakilerden en az biri olan ' den daha iyi bir dönüştürme hedefi vardır:Given two different types T1 and T2, T1 is a better conversion target than T2 if no implicit conversion from T2 to T1 exists, and at least one of the following holds:

  • Öğesinden bir örtük dönüşüm T1 T2 varAn implicit conversion from T1 to T2 exists
  • T1 bir temsilci türü D1 veya ifade ağacı türü Expression<D1> , T2 bir temsilci türü ya da bir D2 ifade ağacı türü, bir Expression<D2> D1 dönüş türüne S1 ve aşağıdaki ayrı tutmalara sahiptir:T1 is either a delegate type D1 or an expression tree type Expression<D1>, T2 is either a delegate type D2 or an expression tree type Expression<D2>, D1 has a return type S1 and one of the following holds:
    • D2 void döndürüyorD2 is void returning
    • D2 , bir dönüş türüne sahiptir S2 ve S1 şundan daha iyi bir dönüştürme hedefi S2D2 has a return type S2, and S1 is a better conversion target than S2
  • T1 , Task<S1> , T2 Task<S2> ve ' S1 den daha iyi bir dönüştürme hedefi S2T1 is Task<S1>, T2 is Task<S2>, and S1 is a better conversion target than S2
  • T1 , S1 veya S1? nerede S1 imzalı bir integral türüdür, T2 S2 veya S2? nerede S2 işaretsiz bir integral türüdür.T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. Özellikle:Specifically:
    • S1 ,,, sbyte S2 byte ushort uint veya ulongS1 is sbyte and S2 is byte, ushort, uint, or ulong
    • S1 ,,, short S2 ushort uint veya ulongS1 is short and S2 is ushort, uint, or ulong
    • S1 , int ve S2 uint , veya ulongS1 is int and S2 is uint, or ulong
    • S1, long ve S2``ulongS1 is long and S2 is ulong

Genel sınıflarda aşırı yüklemeOverloading in generic classes

Belirtilen imzaların benzersiz olması gerekir, ancak tür bağımsız değişkenlerinin değişimi de özdeş imzalara neden olabilir.While signatures as declared must be unique, it is possible that substitution of type arguments results in identical signatures. Bu gibi durumlarda, yukarıdaki aşırı yükleme çözümünün bağlama kuralları en belirli üyeyi seçer.In such cases, the tie-breaking rules of overload resolution above will pick the most specific member.

Aşağıdaki örneklerde, bu kurala göre geçerli ve geçersiz olan aşırı yüklemeler gösterilmektedir:The following examples show overloads that are valid and invalid according to this rule:

interface I1<T> {...}

interface I2<T> {...}

class G1<U>
{
    int F1(U u);                  // Overload resolution for G<int>.F1
    int F1(int i);                // will pick non-generic

    void F2(I1<U> a);             // Valid overload
    void F2(I2<U> a);
}

class G2<U,V>
{
    void F3(U u, V v);            // Valid, but overload resolution for
    void F3(V v, U u);            // G2<int,int>.F3 will fail

    void F4(U u, I1<V> v);        // Valid, but overload resolution for    
    void F4(I1<V> v, U u);        // G2<I1<int>,int>.F4 will fail

    void F5(U u1, I1<V> v2);      // Valid overload
    void F5(V v1, U u2);

    void F6(ref U u);             // valid overload
    void F6(out V v);
}

Dinamik aşırı yükleme çözümlemesi için derleme zamanı denetimiCompile-time checking of dynamic overload resolution

Dinamik olarak bağlı işlemler için, derleme zamanında çözümleme için olası aday adayları bilinmiyor.For most dynamically bound operations the set of possible candidates for resolution is unknown at compile-time. Ancak, bazı durumlarda aday kümesi derleme zamanında bilinir:In certain cases, however the candidate set is known at compile-time:

  • Dinamik bağımsız değişkenlerle statik yöntem çağrılarıStatic method calls with dynamic arguments
  • Örnek yöntemi, alıcının dinamik bir ifade olmadığı yerleri çağırırInstance method calls where the receiver is not a dynamic expression
  • Alıcının dinamik bir ifade olmadığı Dizin Oluşturucu çağrılarıIndexer calls where the receiver is not a dynamic expression
  • Dinamik bağımsız değişkenlerle Oluşturucu çağrılarıConstructor calls with dynamic arguments

Bu durumlarda, her bir aday için sınırlı bir derleme zamanı denetimi gerçekleştirilerek, bunlardan herhangi birinin çalışma zamanında uygulayıp uygulamamadığını görebilirler. Bu denetim aşağıdaki adımlardan oluşur:In these cases a limited compile-time check is performed for each candidate to see if any of them could possibly apply at run-time.This check consists of the following steps:

  • Kısmi tür çıkarımı: türünün bağımsız değişkenine doğrudan veya dolaylı olarak bağımlı olmayan herhangi bir tür bağımsız değişkeni, dynamic tür çıkarımıkuralları kullanılarak algılanır.Partial type inference: Any type argument that does not depend directly or indirectly on an argument of type dynamic is inferred using the rules of Type inference. Kalan tür bağımsız değişkenleri bilinmiyor.The remaining type arguments are unknown.
  • Kısmi uygulanabilirlik denetimi: uygulanabilirliği, uygulanabilir işlev üyesinegöre denetlenir, ancak türleri bilinmiyor olan parametreleri yoksayar.Partial applicability check: Applicability is checked according to Applicable function member, but ignoring parameters whose types are unknown.
  • Bu testi hiçbir aday geçirmediğinde, derleme zamanı hatası oluşur.If no candidate passes this test, a compile-time error occurs.

İşlev üyesi çağırmaFunction member invocation

Bu bölümde, belirli bir işlev üyesini çağırmak için çalışma zamanında gerçekleşen işlem açıklanmaktadır.This section describes the process that takes place at run-time to invoke a particular function member. Bir bağlama zamanı işleminin, büyük olasılıkla bir aday işlev üyesi kümesine aşırı yükleme çözümlemesi uygulayarak, çağırmak için belirli bir üyeyi daha önce belirlediğini kabul edilir.It is assumed that a binding-time process has already determined the particular member to invoke, possibly by applying overload resolution to a set of candidate function members.

Çağırma işlemini açıklama amaçlarıyla, işlev üyeleri iki kategoriye ayrılmıştır:For purposes of describing the invocation process, function members are divided into two categories:

  • Statik işlev üyeleri.Static function members. Bunlar örnek oluşturucular, statik yöntemler, statik özellik erişimcileri ve Kullanıcı tanımlı işleçlerdir.These are instance constructors, static methods, static property accessors, and user-defined operators. Statik işlev üyeleri her zaman sanal değildir.Static function members are always non-virtual.
  • Örnek işlevi üyeleri.Instance function members. Bunlar örnek yöntemleridir, örnek özellik erişimcileri ve Dizin Oluşturucu erişimcileri.These are instance methods, instance property accessors, and indexer accessors. Örnek işlevi üyeleri sanal olmayan veya sanal değil, her zaman belirli bir örnek üzerinde çağrılır.Instance function members are either non-virtual or virtual, and are always invoked on a particular instance. Örnek bir örnek ifadesi tarafından hesaplanır ve işlev üyesi this (Bu erişim) içinde erişilebilir hale gelir.The instance is computed by an instance expression, and it becomes accessible within the function member as this (This access).

Bir işlev üye çağrısının çalışma zamanı işleme aşağıdaki adımlardan oluşur; burada M işlev üyesi, ve M bir örnek üyesiyse E örnek ifadedir:The run-time processing of a function member invocation consists of the following steps, where M is the function member and, if M is an instance member, E is the instance expression:

  • MBir statik işlev üyesiyse:If M is a static function member:

  • M, Bir value_type bir örnek işlev üyesiyse bildirilmiştir:If M is an instance function member declared in a value_type:

    • E değerlendirilir.E is evaluated. Bu değerlendirme bir özel duruma neden olursa başka bir adım yürütülmez.If this evaluation causes an exception, then no further steps are executed.
    • EBir değişken olarak sınıflandırılmadıysa, türünün geçici bir yerel değişkeni E oluşturulur ve değeri E Bu değişkene atanır.If E is not classified as a variable, then a temporary local variable of E's type is created and the value of E is assigned to that variable. E sonra bu geçici yerel değişkene bir başvuru olarak yeniden sınıflanır.E is then reclassified as a reference to that temporary local variable. Geçici değişkene, içinde olduğu gibi this erişilebilir M , ancak başka bir şekilde erişilebilir.The temporary variable is accessible as this within M, but not in any other way. Bu nedenle, E çağıranın öğesine yaptığı değişiklikleri gözlemlemek için yalnızca doğru bir değişken olduğunda M this .Thus, only when E is a true variable is it possible for the caller to observe the changes that M makes to this.
    • Bağımsız değişken listesi, bağımsız değişken listelerindeaçıklandığı şekilde değerlendirilir.The argument list is evaluated as described in Argument lists.
    • M çağrılır.M is invoked. Tarafından başvurulan değişken E tarafından başvurulan değişken olur this .The variable referenced by E becomes the variable referenced by this.
  • M, Bir reference_type bir örnek işlev üyesiyse bildirilmiştir:If M is an instance function member declared in a reference_type:

    • E değerlendirilir.E is evaluated. Bu değerlendirme bir özel duruma neden olursa başka bir adım yürütülmez.If this evaluation causes an exception, then no further steps are executed.
    • Bağımsız değişken listesi, bağımsız değişken listelerindeaçıklandığı şekilde değerlendirilir.The argument list is evaluated as described in Argument lists.
    • Türü E bir value_type ise, türüne dönüştürmek için bir paketleme dönüştürmesi (kutulama dönüştürmeleri) gerçekleştirilir E object ve E Aşağıdaki adımlarda türünde olduğu kabul edilir object .If the type of E is a value_type, a boxing conversion (Boxing conversions) is performed to convert E to type object, and E is considered to be of type object in the following steps. Bu durumda, M yalnızca bir üyesi olabilir System.Object .In this case, M could only be a member of System.Object.
    • Öğesinin değeri E geçerli olacak şekilde işaretlendi.The value of E is checked to be valid. Değeri E ise null , bir System.NullReferenceException atılır ve başka bir adım yürütülmez.If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
    • Çağrılacak işlev üyesi uygulama belirlenir:The function member implementation to invoke is determined:
      • Bağlama zamanı türü E bir arabirim ise, çağrılacak işlev üyesi M tarafından başvurulan örneğin çalışma zamanı türü tarafından sağlanmasıdır E .If the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. Bu işlev üyesi, M tarafından başvurulan örneğin çalışma zamanı türü tarafından verilen uygulamanın belirlenmesi için arabirim eşleme kuralları (arabirim eşleme) uygulanarak belirlenir E .This function member is determined by applying the interface mapping rules (Interface mapping) to determine the implementation of M provided by the run-time type of the instance referenced by E.
      • Aksi takdirde, M bir sanal işlev üyesiyse, çağrılacak işlev üyesi M tarafından başvurulan örneğin çalışma zamanı türü tarafından sağlanmasıdır E .Otherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. Bu işlev üyesi, M tarafından başvurulan örneğin çalışma zamanı türüne göre en çok türetilmiş uygulamayı (sanal yöntemler) belirlemek için kurallar uygulanarak belirlenir E .This function member is determined by applying the rules for determining the most derived implementation (Virtual methods) of M with respect to the run-time type of the instance referenced by E.
      • Aksi takdirde, M sanal olmayan bir işlev üyesi ve çağrılacak işlev üyesi M kendisi olur.Otherwise, M is a non-virtual function member, and the function member to invoke is M itself.
    • Yukarıdaki adımda belirlenen işlev üyesi uygulama çağrılır.The function member implementation determined in the step above is invoked. Tarafından başvurulan nesne E tarafından başvurulan nesne haline gelir this .The object referenced by E becomes the object referenced by this.

Paketlenmiş örneklerde etkinleştirmeleriInvocations on boxed instances

Bir value_type uygulanan bir işlev üyesi, aşağıdaki durumlarda bu value_type paketlenmiş bir örneği aracılığıyla çağrılabilir:A function member implemented in a value_type can be invoked through a boxed instance of that value_type in the following situations:

  • İşlev üyesi türden devralınan bir yöntemin bir öğesi olduğunda override object ve türünün bir örnek ifadesi aracılığıyla çağrıldığında object .When the function member is an override of a method inherited from type object and is invoked through an instance expression of type object.
  • İşlev üyesi bir arabirim işlevi üyesinin bir uygulamasıdır ve bir interface_type örnek ifadesi aracılığıyla çağrılır.When the function member is an implementation of an interface function member and is invoked through an instance expression of an interface_type.
  • İşlev üyesi bir temsilci aracılığıyla çağrıldığında.When the function member is invoked through a delegate.

Bu durumlarda kutulanmış örnek, value_type bir değişken içeren olarak değerlendirilir ve bu değişken, this işlev üye çağrısı içinde tarafından başvurulan değişken olur.In these situations, the boxed instance is considered to contain a variable of the value_type, and this variable becomes the variable referenced by this within the function member invocation. Özellikle bu, bir işlev üyesinin paketlenmiş bir örnek üzerinde çağrıldığı anlamına gelir, işlev üyesinin kutulanmış örnekte bulunan değeri değiştirmesi mümkündür.In particular, this means that when a function member is invoked on a boxed instance, it is possible for the function member to modify the value contained in the boxed instance.

Birincil ifadelerPrimary expressions

Birincil ifadeler, en basit ifade biçimlerini içerir.Primary expressions include the simplest forms of expressions.

primary_expression
    : primary_no_array_creation_expression
    | array_creation_expression
    ;

primary_no_array_creation_expression
    : literal
    | interpolated_string_expression
    | simple_name
    | parenthesized_expression
    | member_access
    | invocation_expression
    | element_access
    | this_access
    | base_access
    | post_increment_expression
    | post_decrement_expression
    | object_creation_expression
    | delegate_creation_expression
    | anonymous_object_creation_expression
    | typeof_expression
    | checked_expression
    | unchecked_expression
    | default_value_expression
    | nameof_expression
    | anonymous_method_expression
    | primary_no_array_creation_expression_unsafe
    ;

Birincil ifadeler array_creation_expression s ve primary_no_array_creation_expression s arasında bölünür.Primary expressions are divided between array_creation_expression s and primary_no_array_creation_expression s. Dizi oluşturma-ifadesini diğer basit ifade formlarıyla birlikte listelemek yerine bu şekilde düşünerek, dilbilgisinde,Treating array-creation-expression in this way, rather than listing it along with the other simple expression forms, enables the grammar to disallow potentially confusing code such as

object o = new int[3][1];

Aksi takdirdewhich would otherwise be interpreted as

object o = (new int[3])[1];

Değişmez DeğerlerLiterals

Değişmez değer (sabit değerler) içeren bir primary_expression değer olarak sınıflandırıldı.A primary_expression that consists of a literal (Literals) is classified as a value.

Ara değerli dizelerInterpolated strings

İnterpolated_string_expression , bir işaretinden sonra, $ boşluklar, ve ile ayrılmış { } ifadeler ve biçimlendirme belirtimleri içeren normal ya da tam bir dize değişmez değeri oluşur.An interpolated_string_expression consists of a $ sign followed by a regular or verbatim string literal, wherein holes, delimited by { and }, enclose expressions and formatting specifications. Enterpolasyonlu dize ifadesi, enterpolasyonlu dize sabit değerleriiçinde açıklandığı gibi ayrı belirteçlere bölünmüş bir interpolated_string_literal sonucudur.An interpolated string expression is the result of an interpolated_string_literal that has been broken up into individual tokens, as described in Interpolated string literals.

interpolated_string_expression
    : '$' interpolated_regular_string
    | '$' interpolated_verbatim_string
    ;

interpolated_regular_string
    : interpolated_regular_string_whole
    | interpolated_regular_string_start interpolated_regular_string_body interpolated_regular_string_end
    ;

interpolated_regular_string_body
    : interpolation (interpolated_regular_string_mid interpolation)*
    ;

interpolation
    : expression
    | expression ',' constant_expression
    ;

interpolated_verbatim_string
    : interpolated_verbatim_string_whole
    | interpolated_verbatim_string_start interpolated_verbatim_string_body interpolated_verbatim_string_end
    ;

interpolated_verbatim_string_body
    : interpolation (interpolated_verbatim_string_mid interpolation)+
    ;

Bir ilişkilendirmedeki constant_expression için örtük bir dönüştürme olmalıdır int .The constant_expression in an interpolation must have an implicit conversion to int.

Bir interpolated_string_expression değer olarak sınıflandırılır.An interpolated_string_expression is classified as a value. System.IFormattable System.FormattableString Örtülü olarak bulunan bir dize dönüştürmesi (örtük olarak enterpolasyonlu dize dönüştürmeleri) öğesine veya öğesine hemen dönüştürülürse, enterpolasyonlu dize ifadesinde bu tür bulunur.If it is immediately converted to System.IFormattable or System.FormattableString with an implicit interpolated string conversion (Implicit interpolated string conversions), the interpolated string expression has that type. Aksi takdirde, türü vardır string .Otherwise, it has the type string.

Enterpolasyonlu bir dizenin türü System.IFormattable veya ise System.FormattableString , anlamı öğesine bir çağrıdır System.Runtime.CompilerServices.FormattableStringFactory.Create .If the type of an interpolated string is System.IFormattable or System.FormattableString, the meaning is a call to System.Runtime.CompilerServices.FormattableStringFactory.Create. Tür ise string , ifadenin anlamı öğesine bir çağrıdır string.Format .If the type is string, the meaning of the expression is a call to string.Format. Her iki durumda da, çağrının bağımsız değişken listesi, her ilişkilendirme için yer tutucular içeren bir biçim dizesi değişmez değerinden ve yer sahiplerine karşılık gelen her bir ifade için bir bağımsız değişkenle oluşur.In both cases, the argument list of the call consists of a format string literal with placeholders for each interpolation, and an argument for each expression corresponding to the place holders.

Biçim dizesi değişmez değeri aşağıdaki gibi oluşturulur, burada N interpolated_string_expression enterpolasyonun sayısıdır:The format string literal is constructed as follows, where N is the number of interpolations in the interpolated_string_expression:

  • Bir interpolated_regular_string_whole veya interpolated_verbatim_string_whole işareti izliyorsa $ , biçim dize sabit değeri bu belirteç olur.If an interpolated_regular_string_whole or an interpolated_verbatim_string_whole follows the $ sign, then the format string literal is that token.
  • Aksi takdirde, biçim dizesi değişmez değeri şunlardan oluşur:Otherwise, the format string literal consists of:
    • İlk interpolated_regular_string_start veya interpolated_verbatim_string_startFirst the interpolated_regular_string_start or interpolated_verbatim_string_start
    • Sonrasında her bir sayı I için 0 N-1 :Then for each number I from 0 to N-1:
      • Öğesinin ondalık temsili IThe decimal representation of I
      • Ardından, karşılık gelen enterpolasyon bir constant_expression sahipse, bir , (virgül) ve ardından constant_expression değerinin ondalık temsili.Then, if the corresponding interpolation has a constant_expression, a , (comma) followed by the decimal representation of the value of the constant_expression
      • İnterpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_mid veya interpolated_verbatim_string_end karşılık gelen ilişkilendirmeyi hemen takip edin.Then the interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_mid or interpolated_verbatim_string_end immediately following the corresponding interpolation.

Sonraki bağımsız değişkenler, sırasıyla enterpolasyonların (varsa) ifadeleridir .The subsequent arguments are simply the expressions from the interpolations (if any), in order.

TODO: örnekler.TODO: examples.

Basit adlarSimple names

Simple_name bir tanımlayıcıdan, isteğe bağlı olarak bir tür bağımsız değişken listesi tarafından oluşur:A simple_name consists of an identifier, optionally followed by a type argument list:

simple_name
    : identifier type_argument_list?
    ;

Simple_name , ya da I formundadır I<A1,...,Ak> , burada I tek tanımlayıcıdır ve <A1,...,Ak> isteğe bağlı bir type_argument_list.A simple_name is either of the form I or of the form I<A1,...,Ak>, where I is a single identifier and <A1,...,Ak> is an optional type_argument_list. Type_argument_list belirtilmediğinde sıfır olduğunu düşünün K .When no type_argument_list is specified, consider K to be zero. Simple_name değerlendirilir ve aşağıdaki gibi sınıflandırılacaktır:The simple_name is evaluated and classified as follows:

  • KSıfırsa ve simple_name bir blok içinde görünürse ve blok(ya da kapsayan bloğun) yerel değişken bildirim alanı (Bildirimler), ada sahip bir yerel değişken, parametre veya sabit içeriyorsa  I , simple_name bu yerel değişkene, parametreye veya sabitine başvurur ve değişken veya değer olarak sınıflandırılacaktır.If K is zero and the simple_name appears within a block and if the block's (or an enclosing block's) local variable declaration space (Declarations) contains a local variable, parameter or constant with name I, then the simple_name refers to that local variable, parameter or constant and is classified as a variable or value.

  • KSıfırsa ve simple_name bir genel yöntem bildiriminin gövdesinde görünürse ve bu bildirim, adında bir tür parametresi içeriyorsa  I , simple_name bu tür parametresine başvurur.If K is zero and the simple_name appears within the body of a generic method declaration and if that declaration includes a type parameter with name I, then the simple_name refers to that type parameter.

  • Aksi halde, her örnek türü için  T (örnek türü), hemen kapsayan tür bildiriminin örnek türüyle başlar ve her bir kapsayan sınıfın ya da yapı bildiriminin örnek türüne (varsa) devam edin:Otherwise, for each instance type T (The instance type), starting with the instance type of the immediately enclosing type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):

    • KSıfırsa ve bildirimi, T adında bir tür parametresi içeriyorsa  I , simple_name bu tür parametreye başvurur.If K is zero and the declaration of T includes a type parameter with name I, then the simple_name refers to that type parameter.
    • Aksi halde, içindeki tür bağımsız değişkenleriyle içindeki üye araması (üye arama) I T K   bir eşleşme üretir:Otherwise, if a member lookup (Member lookup) of I in T with K type arguments produces a match:
      • THemen kapsayan sınıfın veya yapı türünün örnek türü ise ve arama bir veya daha fazla yöntemi tanımlarsa, sonuç, ilişkili bir örnek ifadesi olan bir yöntem grubudur this .If T is the instance type of the immediately enclosing class or struct type and the lookup identifies one or more methods, the result is a method group with an associated instance expression of this. Bir tür bağımsız değişken listesi belirtilmişse, genel bir yöntemi (Yöntem etkinleştirmeleri) çağırmak için kullanılır.If a type argument list was specified, it is used in calling a generic method (Method invocations).
      • Aksi takdirde, T arama bir örnek üye tanımlarsa ve başvuru bir örnek oluşturucusunun, örnek yönteminin veya örnek erişimcisinin gövdesinde gerçekleşirse, sonuç formun bir üye erişimi (üye erişimi) ile aynıdır. Bu, hemen kapsayan sınıf veya yapı türünün örnek türüdür this.I .Otherwise, if T is the instance type of the immediately enclosing class or struct type, if the lookup identifies an instance member, and if the reference occurs within the body of an instance constructor, an instance method, or an instance accessor, the result is the same as a member access (Member access) of the form this.I. Bu yalnızca sıfır olduğunda meydana gelebilir K .This can only happen when K is zero.
      • Aksi takdirde, sonuç formun veya bir üye erişimi (üye erişimi) ile aynıdır T.I T.I<A1,...,Ak> .Otherwise, the result is the same as a member access (Member access) of the form T.I or T.I<A1,...,Ak>. Bu durumda, simple_name bir örnek üyesine başvurması için bağlama zamanı hatası olur.In this case, it is a binding-time error for the simple_name to refer to an instance member.
  • Aksi takdirde,  N simple_name gerçekleştiği ad alanından başlayıp, kapsayan her ad alanıyla (varsa) devam ederek ve genel ad alanıyla sona ermek üzere, aşağıdaki adımlar bir varlık bulunana kadar değerlendirilir:Otherwise, for each namespace N, starting with the namespace in which the simple_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:

    • KSıfırsa ve I içindeki bir ad alanının adı ise  N :If K is zero and I is the name of a namespace in N, then:
      • Simple_name gerçekleştiği konum için bir ad alanı bildirimi alıyorsa N ve ad alanı bildirimi adı bir ad alanı veya türle ilişkilendiren bir extern_alias_directive veya using_alias_directive içeriyorsa  I , simple_name belirsizdir ve derleme zamanı hatası oluşur.If the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
      • Aksi takdirde simple_name , içinde adlı ad alanını ifade I eder N .Otherwise, the simple_name refers to the namespace named I in N.
    • Aksi takdirde, N ad  I ve K tür parametrelerine sahip erişilebilir bir tür içeriyorsa   :Otherwise, if N contains an accessible type having name I and K type parameters, then:
      • KSıfırsa ve simple_name gerçekleştiği konum için bir ad alanı bildirimi alınır N ve ad alanı bildirimi adı bir ad alanı veya türle ilişkilendiren bir extern_alias_directive veya using_alias_directive içeriyorsa  I , simple_name belirsizdir ve bir derleme zamanı hatası oluşur.If K is zero and the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
      • Aksi takdirde namespace_or_type_name , verilen tür bağımsız değişkenleriyle oluşturulan türe başvurur.Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
    • Aksi takdirde, simple_name gerçekleştiği konum için bir ad alanı bildirimi alınır  N :Otherwise, if the location where the simple_name occurs is enclosed by a namespace declaration for N:
      • KSıfırsa ve ad alanı bildirimi, adı bir içeri aktarılan ad alanı veya türle ilişkilendiren bir extern_alias_directive veya using_alias_directive içeriyorsa  I simple_name bu ad alanına veya türe başvurur.If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the simple_name refers to that namespace or type.
      • Aksi takdirde, using_namespace_directive s ve ad alanı bildiriminin using_static_directive tarafından içeri aktarılan ad alanları ve tür bildirimleri tam olarak bir erişilebilir tür veya uzantı olmayan statik üye içeriyorsa  I , ad ve K   tür parametrelerine sahip olan simple_name , bu tür veya üyeyi verilen tür bağımsız değişkenleriyle oluşturulan üyeye başvurur.Otherwise, if the namespaces and type declarations imported by the using_namespace_directive s and using_static_directive s of the namespace declaration contain exactly one accessible type or non-extension static member having name I and K type parameters, then the simple_name refers to that type or member constructed with the given type arguments.
      • Aksi takdirde, ad alanı bildiriminin using_namespace_directive tarafından içeri aktarılan ad alanları ve türler, ad ve tür parametrelerine sahip birden fazla erişilebilir tür ya da uzantı dışı statik üye içeriyorsa  I K   simple_name belirsizdir ve bir hata oluşur.Otherwise, if the namespaces and types imported by the using_namespace_directive s of the namespace declaration contain more than one accessible type or non-extension-method static member having name I and K type parameters, then the simple_name is ambiguous and an error occurs.

    Bu adımın tamamı bir namespace_or_type_name (ad alanı ve tür adları) işlenirken ilgili adıma tam olarak paralel olduğunu unutmayın.Note that this entire step is exactly parallel to the corresponding step in the processing of a namespace_or_type_name (Namespace and type names).

  • Aksi takdirde, simple_name tanımsız olur ve derleme zamanı hatası oluşur.Otherwise, the simple_name is undefined and a compile-time error occurs.

Parantez içinde ifadelerParenthesized expressions

Parenthesized_expression parantez içine alınmış bir ifadeden oluşur.A parenthesized_expression consists of an expression enclosed in parentheses.

parenthesized_expression
    : '(' expression ')'
    ;

Parantez içindeki ifade hesaplanarak bir parenthesized_expression değerlendirilir.A parenthesized_expression is evaluated by evaluating the expression within the parentheses. Parantez içindeki ifade bir ad alanı veya tür alıyorsa, bir derleme zamanı hatası oluşur.If the expression within the parentheses denotes a namespace or type, a compile-time error occurs. Aksi takdirde, parenthesized_expression sonucu içerilen ifadenin değerlendirmesinin sonucudur.Otherwise, the result of the parenthesized_expression is the result of the evaluation of the contained expression.

Üye erişimiMember access

Bir member_access primary_expression, predefined_type ya da qualified_alias_member, ardından bir " . " belirteci ve ardından bir tanımlayıcı tarafından ve isteğe bağlı olarak bir type_argument_list tarafından oluşur.A member_access consists of a primary_expression, a predefined_type, or a qualified_alias_member, followed by a "." token, followed by an identifier, optionally followed by a type_argument_list.

member_access
    : primary_expression '.' identifier type_argument_list?
    | predefined_type '.' identifier type_argument_list?
    | qualified_alias_member '.' identifier
    ;

predefined_type
    : 'bool'   | 'byte'  | 'char'  | 'decimal' | 'double' | 'float' | 'int' | 'long'
    | 'object' | 'sbyte' | 'short' | 'string'  | 'uint'   | 'ulong' | 'ushort'
    ;

Qualified_alias_member üretim, ad alanı diğer adı niteleyicilerinegöre tanımlanır.The qualified_alias_member production is defined in Namespace alias qualifiers.

Member_access , ya da biçimindedir E.I E.I<A1, ..., Ak> , burada E bir birincil ifadedir, I tek bir tanımlayıcıdır ve <A1, ..., Ak> isteğe bağlı bir type_argument_list.A member_access is either of the form E.I or of the form E.I<A1, ..., Ak>, where E is a primary-expression, I is a single identifier and <A1, ..., Ak> is an optional type_argument_list. Type_argument_list belirtilmediğinde sıfır olduğunu düşünün K .When no type_argument_list is specified, consider K to be zero.

Türü primary_expression olan member_access dynamic dinamik olarak bağlı (dinamik bağlama).A member_access with a primary_expression of type dynamic is dynamically bound (Dynamic binding). Bu durumda, derleyici üye erişimini türü özellik erişimi olarak sınıflandırır dynamic .In this case the compiler classifies the member access as a property access of type dynamic. Member_access anlamını belirlemede aşağıdaki kurallar, primary_expression derleme zamanı türü yerine çalışma zamanı türü kullanılarak çalışma zamanında uygulanır.The rules below to determine the meaning of the member_access are then applied at run-time, using the run-time type instead of the compile-time type of the primary_expression. Bu çalışma zamanı sınıflandırması bir yöntem grubuna yol açar, üye erişimi bir invocation_expression primary_expression olmalıdır.If this run-time classification leads to a method group, then the member access must be the primary_expression of an invocation_expression.

Member_access değerlendirilir ve aşağıdaki gibi sınıflandırılacaktır:The member_access is evaluated and classified as follows:

  • KSıfır ise ve E bir ad alanı ise ve E adında iç içe geçmiş bir ad alanı içeriyorsa sonuç,  I Bu ad alanıdır.If K is zero and E is a namespace and E contains a nested namespace with name I, then the result is that namespace.
  • Aksi halde, E bir ad alanı ise ve E ad ve tür parametrelerine sahip erişilebilir bir tür içeriyorsa  I K   , sonuç, belirtilen tür bağımsız değişkenleriyle oluşturulan türüdür.Otherwise, if E is a namespace and E contains an accessible type having name I and K type parameters, then the result is that type constructed with the given type arguments.
  • Bir E predefined_type veya bir tür olarak sınıflandırılan bir primary_expression , E bir tür parametresi değilse ve ' de tür parametrelerine sahip bir üye araması (üye araması) I E K   bir eşleşme üretirse E.I aşağıdaki şekilde değerlendirilir ve sınıflandırıldı:If E is a predefined_type or a primary_expression classified as a type, if E is not a type parameter, and if a member lookup (Member lookup) of I in E with K type parameters produces a match, then E.I is evaluated and classified as follows:
    • IBir tür tanımlarsa, sonuç, belirtilen tür bağımsız değişkenleriyle oluşturulan türüdür.If I identifies a type, then the result is that type constructed with the given type arguments.
    • IBir veya daha fazla yöntemi tanımlarsa, sonuç ilişkili örnek ifadesi olmayan bir yöntem grubudur.If I identifies one or more methods, then the result is a method group with no associated instance expression. Bir tür bağımsız değişken listesi belirtilmişse, genel bir yöntemi (Yöntem etkinleştirmeleri) çağırmak için kullanılır.If a type argument list was specified, it is used in calling a generic method (Method invocations).
    • IBir özelliği tanımlarsa static sonuç, ilişkili örnek ifadesi olmayan bir özellik erişimiydi.If I identifies a static property, then the result is a property access with no associated instance expression.
    • IBir alanı tanımlarsa static :If I identifies a static field:
      • Alanı ise readonly ve başvuru, alanın bildirildiği sınıf veya yapının statik oluşturucusunun dışında oluşursa, sonuç bir değerdir, yani içindeki statik alanın değeri  I  E .If the field is readonly and the reference occurs outside the static constructor of the class or struct in which the field is declared, then the result is a value, namely the value of the static field I in E.
      • Aksi takdirde, sonuç bir değişkendir, yani içindeki statik alan  I  E .Otherwise, the result is a variable, namely the static field I in E.
    • IBir olayı tanımlarsa static :If I identifies a static event:
      • Başvuru, olayın bildirildiği sınıf veya yapı içinde oluşursa ve olay event_accessor_declarations (Olaylar) olmadan bildirilirse, E.I tam olarak I bir statik alan gibi işlenir.If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), then E.I is processed exactly as if I were a static field.
      • Aksi halde, sonuç, ilişkili örnek ifadesi olmayan bir olay erişimiydi.Otherwise, the result is an event access with no associated instance expression.
    • IBir sabiti tanımlarsa, sonuç bir değerdir, yani bu sabit değeridir.If I identifies a constant, then the result is a value, namely the value of that constant.
    • IBir numaralandırma üyesini tanımlarsa, sonuç bir değerdir, yani bu numaralandırma üyesinin değeri.If I identifies an enumeration member, then the result is a value, namely the value of that enumeration member.
    • Aksi takdirde, E.I geçersiz bir üye başvurusu ve derleme zamanı hatası oluşur.Otherwise, E.I is an invalid member reference, and a compile-time error occurs.
  • EBir özellik erişimse, Dizin Oluşturucu erişimi, değişken veya değer, tür  T bağımsız değişkenleriyle içindeki içindeki üye araması (üye arama) bir I T K   eşleşme üretir E.I ve aşağıdaki gibi değerlendirilir ve sınıflandırılacaktır:If E is a property access, indexer access, variable, or value, the type of which is T, and a member lookup (Member lookup) of I in T with K type arguments produces a match, then E.I is evaluated and classified as follows:
    • İlk olarak, E bir özellik veya Dizin Oluşturucu erişimi ise, özellik veya Dizin Oluşturucu erişimi değeri elde edilir (ifadelerin değerleri) ve E bir değer olarak yeniden sınıflanır.First, if E is a property or indexer access, then the value of the property or indexer access is obtained (Values of expressions) and E is reclassified as a value.
    • IBir veya daha fazla yöntemi tanımlarsa sonuç, ilişkili bir örnek ifadesi olan bir yöntem grubudur E .If I identifies one or more methods, then the result is a method group with an associated instance expression of E. Bir tür bağımsız değişken listesi belirtilmişse, genel bir yöntemi (Yöntem etkinleştirmeleri) çağırmak için kullanılır.If a type argument list was specified, it is used in calling a generic method (Method invocations).
    • IBir örnek özelliği tanımlarsa,If I identifies an instance property,
      • Eİse, this I otomatik olarak uygulanan bir özelliği (Otomatik uygulanan özellikler) bir ayarlayıcı olmadan tanımlar ve başvuru bir sınıf veya yapı türü için örnek oluşturucu içinde meydana gelirse, T sonuç bir değişkendir, yani tarafından I verilen örneğinde tarafından verilen otomatik özellik için gizli yedekleme alanı T this .If E is this, I identifies an automatically implemented property (Automatically implemented properties) without a setter, and the reference occurs within an instance constructor for a class or struct type T, then the result is a variable, namely the hidden backing field for the auto-property given by I in the instance of T given by this.
      • Aksi takdirde, sonuç, ilişkili bir örnek ifadesiyle bir özellik erişimiydi  E .Otherwise, the result is a property access with an associated instance expression of E.
    • TBir class_type ve I class_type bir örnek alanını tanımlar:If T is a class_type and I identifies an instance field of that class_type:
      • Değeri E ise null , bir oluşturulur System.NullReferenceException .If the value of E is null, then a System.NullReferenceException is thrown.
      • Aksi halde, alanı ise readonly ve başvuru, alanın bildirildiği sınıfın örnek oluşturucusunun dışında oluşursa, sonuç bir değerdir, yani  I tarafından başvurulan nesnedeki alanın değeri  E .Otherwise, if the field is readonly and the reference occurs outside an instance constructor of the class in which the field is declared, then the result is a value, namely the value of the field I in the object referenced by E.
      • Aksi takdirde sonuç bir değişkendir, yani  I nesnesindeki alanı tarafından başvurulan alan  E .Otherwise, the result is a variable, namely the field I in the object referenced by E.
    • TBir struct_type ve I struct_type bir örnek alanını tanımlar:If T is a struct_type and I identifies an instance field of that struct_type:
      • EBir değer ise veya alan readonly ve başvuru, alanın bildirildiği yapının örnek oluşturucusunun dışında oluşursa, sonuç bir değerdir, yani,  I tarafından verilen yapı örneğindeki alanın değeri  E .If E is a value, or if the field is readonly and the reference occurs outside an instance constructor of the struct in which the field is declared, then the result is a value, namely the value of the field I in the struct instance given by E.
      • Aksi takdirde, sonuç bir değişkendir, yani  I Yapı örneğindeki alanı tarafından verilir  E .Otherwise, the result is a variable, namely the field I in the struct instance given by E.
    • IBir örnek olayı tanımlarsa:If I identifies an instance event:
      • Başvuru, olayın bildirildiği sınıf veya yapı içinde oluşur ve olay event_accessor_declarations (Olaylar) olmadan bildirildiği ve başvuru bir veya işlecinin sol tarafı olarak gerçekleşmediğinde, tam olarak bir += -= E.I örnek alanı olduğu gibi işlenir I .If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), and the reference does not occur as the left-hand side of a += or -= operator, then E.I is processed exactly as if I was an instance field.
      • Aksi takdirde, sonuç, ilişkili bir örnek ifadesiyle bir olay erişimiydi  E .Otherwise, the result is an event access with an associated instance expression of E.
  • Aksi halde, E.I bir uzantı yöntemi çağırma (genişletme yöntemi etkinleştirmeleri) olarak işlemek için bir girişimde bulunuldu.Otherwise, an attempt is made to process E.I as an extension method invocation (Extension method invocations). Bu başarısız olursa, E.I geçersiz bir üye başvurusu ve bir bağlama zamanı hatası oluşur.If this fails, E.I is an invalid member reference, and a binding-time error occurs.

Aynı basit adlar ve tür adlarıIdentical simple names and type names

Formun üye erişiminde, E.I E tek bir tanımlayıcıdır ve E bir simple_name (basit adlar) anlamı bir sabit, alan, özellik, yerel değişken veya E bir type_name (ad alanı ve tür adları) anlamında aynı türde bir parametre ise, her iki olası anlam de buna E izin verilir.In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple_name (Simple names) is a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type_name (Namespace and type names), then both possible meanings of E are permitted. E.I I Her iki durumda da türün bir üyesi olması gerektiğinden, öğesinin iki olası anlamı hiçbir zaman belirsiz değildir E .The two possible meanings of E.I are never ambiguous, since I must necessarily be a member of the type E in both cases. Diğer bir deyişle, kural yalnızca statik üyelere ve E derleme zamanı hatasının gerçekleştiği iç içe türlerine erişime izin verir.In other words, the rule simply permits access to the static members and nested types of E where a compile-time error would otherwise have occurred. Örnek:For example:

struct Color
{
    public static readonly Color White = new Color(...);
    public static readonly Color Black = new Color(...);

    public Color Complement() {...}
}

class A
{
    public Color Color;                // Field Color of type Color

    void F() {
        Color = Color.Black;           // References Color.Black static member
        Color = Color.Complement();    // Invokes Complement() on Color field
    }

    static void G() {
        Color c = Color.White;         // References Color.White static member
    }
}

Dilbilgisi belirsizlikleriGrammar ambiguities

Simple_name (basit adlar) ve member_access (üye erişimi) üretimleri, ifadelerde dilbilgisi için belirsizlikleri verebilir.The productions for simple_name (Simple names) and member_access (Member access) can give rise to ambiguities in the grammar for expressions. Örneğin, ifade:For example, the statement:

F(G<A,B>(7));

iki bağımsız değişkenle bir çağrı olarak yorumlanamıyor F G < A B > (7) .could be interpreted as a call to F with two arguments, G < A and B > (7). Alternatif olarak, F  G iki tür bağımsız değişkeni ve bir normal bağımsız değişken ile genel bir yönteme çağrı olan bir bağımsız değişkenle bir çağrı olarak yorumlanabilecek.Alternatively, it could be interpreted as a call to F with one argument, which is a call to a generic method G with two type arguments and one regular argument.

Bir belirteç dizisi bir simple_name (basit adlar), member_access (üye erişimi) veya pointer_member_access (işaretçi üyesi erişimi) ile biten bir type_argument_list (tür bağımsız değişkenleri) olarak ayrıştırılamıyorsa, kapanış belirtecini izleyen belirteç > incelenir.If a sequence of tokens can be parsed (in context) as a simple_name (Simple names), member_access (Member access), or pointer_member_access (Pointer member access) ending with a type_argument_list (Type arguments), the token immediately following the closing > token is examined. Bunlardan biri iseIf it is one of

(  )  ]  }  :  ;  ,  .  ?  ==  !=  |  ^

ardından type_argument_list simple_name bir parçası olarak tutulur, member_access veya pointer_member_access ve belirteçleri dizisinin diğer olası ayrıştırması atılır.then the type_argument_list is retained as part of the simple_name, member_access or pointer_member_access and any other possible parse of the sequence of tokens is discarded. Aksi takdirde, belirteç dizisinin başka bir olası ayrıştırması olmasa bile type_argument_list simple_name, member_access veya pointer_member_access bir parçası olarak kabul edilmez.Otherwise, the type_argument_list is not considered to be part of the simple_name, member_access or pointer_member_access, even if there is no other possible parse of the sequence of tokens. Bu kuralların bir namespace_or_type_name type_argument_list ayrıştırılırken (ad alanı ve tür adları) uygulanmadığını unutmayın.Note that these rules are not applied when parsing a type_argument_list in a namespace_or_type_name (Namespace and type names). İfadeThe statement

F(G<A,B>(7));

Bu kurala göre, F G iki tür bağımsız değişkeni ve bir normal bağımsız değişken ile genel bir yönteme çağrı olan bir bağımsız değişkenle bir çağrı olarak yorumlanacaktır.will, according to this rule, be interpreted as a call to F with one argument, which is a call to a generic method G with two type arguments and one regular argument. DeyimlerThe statements

F(G < A, B > 7);
F(G < A, B >> 7);

, her biri iki bağımsız değişkenle bir çağrı olarak yorumlanır F .will each be interpreted as a call to F with two arguments. İfadeThe statement

x = F < A > +y;

, bir x = (F < A) > (+y) type_argument_list ve ardından ikili artı işleci gelen bir simple_name olarak değil, daha az işleç, işleç ve birli artı işleci olarak yorumlanır.will be interpreted as a less than operator, greater than operator, and unary plus operator, as if the statement had been written x = (F < A) > (+y), instead of as a simple_name with a type_argument_list followed by a binary plus operator. İfadesindeIn the statement

x = y is C<T> + z;

belirteçler C<T> type_argument_list bir namespace_or_type_name olarak yorumlanır.the tokens C<T> are interpreted as a namespace_or_type_name with a type_argument_list.

Çağırma ifadeleriInvocation expressions

Bir yöntemi çağırmak için bir invocation_expression kullanılır.An invocation_expression is used to invoke a method.

invocation_expression
    : primary_expression '(' argument_list? ')'
    ;

Aşağıdakilerden en az biri tutuyorsa, bir invocation_expression dinamik olarak bağlı (dinamik bağlama):An invocation_expression is dynamically bound (Dynamic binding) if at least one of the following holds:

  • Primary_expression , derleme zamanı türüne sahiptir dynamic .The primary_expression has compile-time type dynamic.
  • İsteğe bağlı argument_list en az bir bağımsız değişkeni derleme zamanı türüne sahip dynamic ve primary_expression bir temsilci türüne sahip değil.At least one argument of the optional argument_list has compile-time type dynamic and the primary_expression does not have a delegate type.

Bu durumda, derleyici invocation_expression türü bir değer olarak sınıflandırır dynamic .In this case the compiler classifies the invocation_expression as a value of type dynamic. İnvocation_expression anlamını öğrenmek için aşağıdaki kurallar, primary_expression ve derleme zamanı türü olan bağımsız değişkenlerden derleme zamanı türü yerine çalışma zamanı türü kullanılarak çalışma zamanında uygulanır dynamic .The rules below to determine the meaning of the invocation_expression are then applied at run-time, using the run-time type instead of the compile-time type of those of the primary_expression and arguments which have the compile-time type dynamic. Primary_expression , derleme zamanı türüne sahip değilse dynamic , yöntem çağrısı, dinamik aşırı yükleme çözümünün derleme zamanı denetimikonusunda açıklandığı gibi sınırlı bir derleme süresi denetimi yapar.If the primary_expression does not have compile-time type dynamic, then the method invocation undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

Bir invocation_expression primary_expression bir yöntem grubu ya da bir delegate_type değeri olmalıdır.The primary_expression of an invocation_expression must be a method group or a value of a delegate_type. Primary_expression bir yöntem grubu ise, invocation_expression bir yöntem çağrıdır (Yöntem etkinleştirmeleri).If the primary_expression is a method group, the invocation_expression is a method invocation (Method invocations). Primary_expression bir delegate_type değeri ise, invocation_expression bir temsilci çağrıdır (temsilci etkinleştirmeleri).If the primary_expression is a value of a delegate_type, the invocation_expression is a delegate invocation (Delegate invocations). Primary_expression bir yöntem grubu veya bir delegate_type değeri değilse, bir bağlama zamanı hatası oluşur.If the primary_expression is neither a method group nor a value of a delegate_type, a binding-time error occurs.

İsteğe bağlı argument_list (bağımsız değişken listeleri), yöntemin parametreleri için değerler veya değişken başvuruları sağlar.The optional argument_list (Argument lists) provides values or variable references for the parameters of the method.

Bir invocation_expression değerlendirilme sonucu aşağıdaki gibi sınıflandırıldı:The result of evaluating an invocation_expression is classified as follows:

  • İnvocation_expression , döndüren bir yöntemi veya temsilciyi çağıralıyorsa void , sonuç Nothing olur.If the invocation_expression invokes a method or delegate that returns void, the result is nothing. Nothing olarak sınıflandırılan bir ifadeye, yalnızca bir statement_expression (ifade deyimleri) bağlamında veya bir lambda_expression (anonim işlev ifadeleri) gövdesinde izin verilir.An expression that is classified as nothing is permitted only in the context of a statement_expression (Expression statements) or as the body of a lambda_expression (Anonymous function expressions). Aksi halde bağlama zamanı hatası oluşur.Otherwise a binding-time error occurs.
  • Aksi takdirde, sonuç Yöntem veya temsilci tarafından döndürülen türün bir değeridir.Otherwise, the result is a value of the type returned by the method or delegate.

Yöntem etkinleştirmeleriMethod invocations

Bir yöntem çağrısı için, invocation_expression primary_expression bir yöntem grubu olmalıdır.For a method invocation, the primary_expression of the invocation_expression must be a method group. Yöntem grubu, çağrılacak bir yöntemi veya çağırmak için belirli bir yöntemi seçebileceğiniz aşırı yüklenmiş yöntemleri belirler.The method group identifies the one method to invoke or the set of overloaded methods from which to choose a specific method to invoke. İkinci durumda, çağrılacak belirli yöntemin belirlenmesi, argument_list bağımsız değişkenlerin türleri tarafından belirtilen bağlamı temel alır.In the latter case, determination of the specific method to invoke is based on the context provided by the types of the arguments in the argument_list.

M(A) M Bir yöntem grubu (büyük olasılıkla bir type_argument_list dahil) ve A isteğe bağlı bir argument_list olan, formun Yöntem çağırma bağlama zamanı işleme, aşağıdaki adımlardan oluşur:The binding-time processing of a method invocation of the form M(A), where M is a method group (possibly including a type_argument_list), and A is an optional argument_list, consists of the following steps:

  • Yöntem çağrısı için aday yöntemler kümesi oluşturulur.The set of candidate methods for the method invocation is constructed. Yöntem grubuyla ilişkili her bir yöntem için F M :For each method F associated with the method group M:
    • FGenel olmayan ise, F Şu durumlarda bir adaydır:If F is non-generic, F is a candidate when:
    • FGeneldir ve M tür bağımsız değişken listesine sahip değilse, F Şu durumlarda bir adaydır:If F is generic and M has no type argument list, F is a candidate when:
      • Tür çıkarımı (tür çıkarımı) başarılı, çağrının tür bağımsız değişkenlerinin bir listesini, veType inference (Type inference) succeeds, inferring a list of type arguments for the call, and
      • Çıkarsanan tür bağımsız değişkenleri karşılık gelen yöntem türü parametreleri yerine eklendikten sonra, F parametre listesindeki tüm oluşturulmuş türler kısıtlamalarını karşılar (kısıtlamalar karşılılar) ve parametre listesi F A (uygulanabilir işlev üyesi) açısından geçerlidir.Once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
    • FGeneldir ve M bir tür bağımsız değişken listesi içeriyorsa, F Şu durumlarda bir adaydır:If F is generic and M includes a type argument list, F is a candidate when:
      • F , tür bağımsız değişkeni listesinde sağlanan sayıda yöntem türü parametreye sahiptir veF has the same number of method type parameters as were supplied in the type argument list, and
      • Tür bağımsız değişkenleri karşılık gelen yöntem türü parametreleri yerine eklendikten sonra, F parametre listesindeki tüm oluşturulmuş türler kısıtlamalarını karşılar (kısıtlamalar karşılamaları) ve parametre listesi F A (uygulanabilir işlev üyesi) açısından geçerlidir.Once the type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
  • Aday yöntemler kümesi yalnızca en türetilmiş türlerden Yöntemler içerecek şekilde azaltılır: küme içindeki her bir yöntem Için, C.F C yöntemin bildirildiği tür olduğu, F taban türünde belirtilen tüm yöntemler C kümeden kaldırılır.The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set. Ayrıca, dışında C bir sınıf türü ise object , bir arabirim türünde belirtilen tüm yöntemler kümeden kaldırılır.Furthermore, if C is a class type other than object, all methods declared in an interface type are removed from the set. (Bu ikinci kural yalnızca Yöntem grubu, nesne dışındaki etkin bir temel sınıfa sahip olan bir tür parametresindeki üye aramasının ve boş olmayan etkin bir arabirim kümesinin sonucu olduğunda etkiler.)(This latter rule only has affect when the method group was the result of a member lookup on a type parameter having an effective base class other than object and a non-empty effective interface set.)
  • Elde edilen aday yöntemler kümesi boşsa, aşağıdaki adımlar üzerinde daha fazla işleme terk edilir ve bunun yerine, çağırma yöntemi çağırma (uzantı yöntemi etkinleştirmeleri) olarak çağrıyı işlemek için bir girişimde bulunuldu.If the resulting set of candidate methods is empty, then further processing along the following steps are abandoned, and instead an attempt is made to process the invocation as an extension method invocation (Extension method invocations). Bu başarısız olursa, geçerli hiçbir yöntem yoktur ve bir bağlama zamanı hatası oluşur.If this fails, then no applicable methods exist, and a binding-time error occurs.
  • Aday Yöntemler kümesinin en iyi yöntemi, aşırı yükleme çözümününaşırı yükleme çözümleme kuralları kullanılarak tanımlanır.The best method of the set of candidate methods is identified using the overload resolution rules of Overload resolution. Tek bir en iyi yöntem tanımlanamıyorsa, yöntem çağırma belirsizdir ve bir bağlama zamanı hatası oluşur.If a single best method cannot be identified, the method invocation is ambiguous, and a binding-time error occurs. Aşırı yükleme çözümlemesi gerçekleştirirken, genel yöntemin parametreleri karşılık gelen yöntem türü parametreleri için tür bağımsız değişkenleri (sağlanan veya çıkartılan) değiştirildikten sonra değerlendirilir.When performing overload resolution, the parameters of a generic method are considered after substituting the type arguments (supplied or inferred) for the corresponding method type parameters.
  • Seçilen en iyi yöntemin son doğrulaması gerçekleştirilir:Final validation of the chosen best method is performed:
    • Yöntem, Yöntem grubu bağlamında onaylanır: en iyi yöntem bir statik yöntem ise, Yöntem grubu bir simple_name veya bir member_access bir tür aracılığıyla sonuçlanmış olmalıdır.The method is validated in the context of the method group: If the best method is a static method, the method group must have resulted from a simple_name or a member_access through a type. En iyi yöntem bir örnek yöntemi ise, Yöntem grubu bir simple_name, bir değişken veya değer aracılığıyla bir member_access veya bir base_access sonuçlanmış olmalıdır.If the best method is an instance method, the method group must have resulted from a simple_name, a member_access through a variable or value, or a base_access. Bu gereksinimlerin hiçbiri doğru değilse, bir bağlama zamanı hatası oluşur.If neither of these requirements is true, a binding-time error occurs.
    • En iyi yöntem genel bir yöntem ise, tür bağımsız değişkenleri (sağlanan veya çıkartılan) genel yöntemde belirtilen kısıtlamalara (karşılayankısıtlamalar) göre denetlenir.If the best method is a generic method, the type arguments (supplied or inferred) are checked against the constraints (Satisfying constraints) declared on the generic method. Herhangi bir tür bağımsız değişkeni tür parametresindeki karşılık gelen kısıtlamayı karşılamaz bir bağlama zamanı hatası oluşur.If any type argument does not satisfy the corresponding constraint(s) on the type parameter, a binding-time error occurs.

Yukarıdaki adımlarla bağlama zamanında bir Yöntem seçildikten ve doğrulandıktan sonra, gerçek çalışma zamanı çağrısı, dinamik aşırı yükleme çözümünün derleme zamanı denetimindeaçıklanan işlev üye çağırma kurallarına göre işlenir.Once a method has been selected and validated at binding-time by the above steps, the actual run-time invocation is processed according to the rules of function member invocation described in Compile-time checking of dynamic overload resolution.

Yukarıda açıklanan çözüm kurallarının sezgisel etkisi şunlardır: bir yöntem çağrısı tarafından çağrılan belirli bir yöntemi bulmak Için, yöntem çağırma tarafından belirtilen türle başlayın ve en az bir adet uygulanabilir, erişilebilir, geçersiz kılma olmayan yöntem bildirimi bulunana kadar devralma zincirini devam edin.The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. Daha sonra tür çıkarımı ve aşırı yükleme çözümlemesini, bu tür içinde belirtilen geçerli, erişilebilir, geçersiz kılma olmayan yöntemler kümesi ve bu nedenle seçilen yöntemi çağırmak için gerçekleştirin.Then perform type inference and overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected. Hiçbir yöntem bulunmazsa, çağırma yöntemini bir genişletme yöntemi çağrısı olarak işlemeyi deneyin.If no method was found, try instead to process the invocation as an extension method invocation.

Genişletme yöntemi etkinleştirmeleriExtension method invocations

Bir yöntem çağrısında (paketlenmiş örneklerde çağırma), formlardan birininIn a method invocation (Invocations on boxed instances) of one of the forms

expr . identifier ( )

expr . identifier ( args )

expr . identifier < typeargs > ( )

expr . identifier < typeargs > ( args )

çağrının normal işlemesi uygulanabilir bir yöntem bulamıyorsa, yapıyı uzantı metodu çağrısı olarak işlemek için bir girişimde bulunuldu.if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. Eğer Expr veya bağımsız değişkenlerin herhangi birinde derleme zamanı türü varsa dynamic , genişletme yöntemleri uygulanmaz.If expr or any of the args has compile-time type dynamic, extension methods will not apply.

Amaç, C karşılık gelen statik yöntem çağrısının gerçekleşmemesi için en iyi type_name bulıledir:The objective is to find the best type_name C, so that the corresponding static method invocation can take place:

C . identifier ( expr )

C . identifier ( expr , args )

C . identifier < typeargs > ( expr )

C . identifier < typeargs > ( expr , args )

Bir genişletme yöntemi Ci.Mj Şu durumlarda uygundur :An extension method Ci.Mj is eligible if:

  • Ci Genel olmayan, iç içe olmayan bir sınıfCi is a non-generic, non-nested class
  • Mj Tanımlayıcı adıThe name of Mj is identifier
  • Mj , yukarıda gösterildiği gibi bağımsız değişkenlere statik bir yöntem olarak uygulandığında erişilebilir ve uygulanabilir olurMj is accessible and applicable when applied to the arguments as a static method as shown above
  • Bir örtük kimlik, başvuru veya paketleme dönüştürmesi, Expr 'den ilk parametresinin türüne sahiptir Mj .An implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.

Araması C Şu şekilde devam eder:The search for C proceeds as follows:

  • En yakın kapsayan ad alanı bildirimiyle başlayarak, kapsayan her bir ad alanı bildirimine devam edin ve kapsayan derleme birimi ile sona ermek üzere, bir dizi genişletme yöntemini bulmak için art arda denemeler yapılır:Starting with the closest enclosing namespace declaration, continuing with each enclosing namespace declaration, and ending with the containing compilation unit, successive attempts are made to find a candidate set of extension methods:
    • Verilen ad alanı veya derleme birimi, uygun genişletme yöntemleriyle genel olmayan tür bildirimlerini doğrudan içeriyorsa Ci Mj , bu uzantı yöntemlerinin kümesi aday kümesidir.If the given namespace or compilation unit directly contains non-generic type declarations Ci with eligible extension methods Mj, then the set of those extension methods is the candidate set.
    • Ci Using_static_declarations tarafından içeri aktarılan ve doğrudan verilen ad alanındaki veya derleme birimindeki using_namespace_directive s tarafından içeri aktarılan ad alanlarında, doğrudan uygun uzantı yöntemlerini içeriyorsa Mj , bu uzantı yöntemlerinin kümesi aday kümesidir.If types Ci imported by using_static_declarations and directly declared in namespaces imported by using_namespace_directive s in the given namespace or compilation unit directly contain eligible extension methods Mj, then the set of those extension methods is the candidate set.
  • Herhangi bir kapsayan ad alanı bildiriminde veya derleme biriminde hiçbir aday kümesi bulunamazsa, derleme zamanı hatası oluşur.If no candidate set is found in any enclosing namespace declaration or compilation unit, a compile-time error occurs.
  • Aksi halde, aşırı yükleme çözümlemesi aday kümesine (aşırı yükleme çözümlemesi) açıklandığı şekilde uygulanır.Otherwise, overload resolution is applied to the candidate set as described in (Overload resolution). Tek bir en iyi yöntem bulunamazsa, derleme zamanı hatası oluşur.If no single best method is found, a compile-time error occurs.
  • C , en iyi yöntemin bir genişletme yöntemi olarak bildirildiği türdür.C is the type within which the best method is declared as an extension method.

CHedef olarak kullanarak, yöntem çağrısı daha sonra bir statik yöntem çağrısı (dinamik aşırı yükleme çözümünün derleme zamanı denetimi) olarak işlenir.Using C as a target, the method call is then processed as a static method invocation (Compile-time checking of dynamic overload resolution).

Önceki kurallar, örnek yöntemlerinin genişletme yöntemlerine göre öncelikli olduğunu, iç ad alanı bildirimlerinde kullanılabilen genişletme yöntemlerinin, dış ad alanı bildirimlerinde bulunan genişletme yöntemlerine göre öncelikli olduğunu ve bir ad alanında doğrudan bildirildiği uzantı yöntemlerinin, bir using namespace yönergesi ile aynı ad alanına aktarılan genişletme yöntemlerine göre öncelikli olduğunu ifade ediyor.The preceding rules mean that instance methods take precedence over extension methods, that extension methods available in inner namespace declarations take precedence over extension methods available in outer namespace declarations, and that extension methods declared directly in a namespace take precedence over extension methods imported into that same namespace with a using namespace directive. Örnek:For example:

public static class E
{
    public static void F(this object obj, int i) { }

    public static void F(this object obj, string s) { }
}

class A { }

class B
{
    public void F(int i) { }
}

class C
{
    public void F(object obj) { }
}

class X
{
    static void Test(A a, B b, C c) {
        a.F(1);              // E.F(object, int)
        a.F("hello");        // E.F(object, string)

        b.F(1);              // B.F(int)
        b.F("hello");        // E.F(object, string)

        c.F(1);              // C.F(object)
        c.F("hello");        // C.F(object)
    }
}

Örnekte, B yöntemi ilk uzantı yöntemine göre önceliklidir ve C yöntemi her iki uzantı yönteminden önceliklidir.In the example, B's method takes precedence over the first extension method, and C's method takes precedence over both extension methods.

public static class C
{
    public static void F(this int i) { Console.WriteLine("C.F({0})", i); }
    public static void G(this int i) { Console.WriteLine("C.G({0})", i); }
    public static void H(this int i) { Console.WriteLine("C.H({0})", i); }
}

namespace N1
{
    public static class D
    {
        public static void F(this int i) { Console.WriteLine("D.F({0})", i); }
        public static void G(this int i) { Console.WriteLine("D.G({0})", i); }
    }
}

namespace N2
{
    using N1;

    public static class E
    {
        public static void F(this int i) { Console.WriteLine("E.F({0})", i); }
    }

    class Test
    {
        static void Main(string[] args)
        {
            1.F();
            2.G();
            3.H();
        }
    }
}

Bu örneğin çıktısı şu şekilde olur:The output of this example is:

E.F(1)
D.G(2)
C.H(3)

D.G``C.G, ' den önceliklidir ve E.F hem hem de üzerinde önceliğe sahip olur D.F C.F .D.G takes precedence over C.G, and E.F takes precedence over both D.F and C.F.

Temsilci etkinleştirmeleriDelegate invocations

Bir temsilci çağrısı için, invocation_expression primary_expression bir delegate_type değeri olmalıdır.For a delegate invocation, the primary_expression of the invocation_expression must be a value of a delegate_type. Ayrıca, delegate_type delegate_type aynı parametre listesi olan bir işlev üyesi olması halinde delegate_type , invocation_expression argument_list göre uygulanabilir (uygulanabilir işlev üyesi) olmalıdır.Furthermore, considering the delegate_type to be a function member with the same parameter list as the delegate_type, the delegate_type must be applicable (Applicable function member) with respect to the argument_list of the invocation_expression.

Formun bir temsilci çağrısı olan çalışma zamanı işleme, D(A) burada bir D delegate_type primary_expression ve A isteğe bağlı bir argument_list, aşağıdaki adımlardan oluşur:The run-time processing of a delegate invocation of the form D(A), where D is a primary_expression of a delegate_type and A is an optional argument_list, consists of the following steps:

  • D değerlendirilir.D is evaluated. Bu değerlendirme bir özel duruma neden olursa başka bir adım yürütülmez.If this evaluation causes an exception, no further steps are executed.
  • Öğesinin değeri D geçerli olacak şekilde işaretlendi.The value of D is checked to be valid. Değeri D ise null , bir System.NullReferenceException atılır ve başka bir adım yürütülmez.If the value of D is null, a System.NullReferenceException is thrown and no further steps are executed.
  • Aksi takdirde, D bir temsilci örneğine başvurudur.Otherwise, D is a reference to a delegate instance. İşlev üyesi etkinleştirmeleri (dinamik aşırı yükleme çözümlemesi Için derleme zamanı denetimi), temsilcinin çağırma listesindeki çağrılabilir varlıkların her birinde gerçekleştirilir.Function member invocations (Compile-time checking of dynamic overload resolution) are performed on each of the callable entities in the invocation list of the delegate. Örnek ve örnek yönteminden oluşan çağrılabilir varlıklar için, çağırma örneği çağrılabilir varlıkta bulunan örneğidir.For callable entities consisting of an instance and instance method, the instance for the invocation is the instance contained in the callable entity.

Öğe erişimiElement access

Bir element_access primary_no_array_creation_expression ve ardından bir " [ " belirteci, ardından bir argument_list ve ardından " ] " belirteci ile oluşur.An element_access consists of a primary_no_array_creation_expression, followed by a "[" token, followed by an argument_list, followed by a "]" token. Argument_list , virgülle ayrılmış bir veya daha fazla bağımsız değişkenden oluşur.The argument_list consists of one or more argument s, separated by commas.

element_access
    : primary_no_array_creation_expression '[' expression_list ']'
    ;

Bir element_access argument_list ref veya bağımsız değişken içermesine izin verilmez out .The argument_list of an element_access is not allowed to contain ref or out arguments.

Aşağıdakilerden en az biri tutuyorsa, bir element_access dinamik olarak bağlı (dinamik bağlama):An element_access is dynamically bound (Dynamic binding) if at least one of the following holds:

  • Primary_no_array_creation_expression , derleme zamanı türüne sahiptir dynamic .The primary_no_array_creation_expression has compile-time type dynamic.
  • Argument_list en az bir ifadesinin derleme zamanı türü var dynamic ve primary_no_array_creation_expression bir dizi türü yok.At least one expression of the argument_list has compile-time type dynamic and the primary_no_array_creation_expression does not have an array type.

Bu durumda, derleyici element_access türü bir değer olarak sınıflandırır dynamic .In this case the compiler classifies the element_access as a value of type dynamic. Element_access anlamını tespit etmek için aşağıdaki kurallar, primary_no_array_creation_expression ve derleme zamanı türü olan argument_list ifadelerin derleme zamanı türü yerine çalışma zamanı türü kullanılarak çalışma zamanında uygulanır dynamic .The rules below to determine the meaning of the element_access are then applied at run-time, using the run-time type instead of the compile-time type of those of the primary_no_array_creation_expression and argument_list expressions which have the compile-time type dynamic. Primary_no_array_creation_expression derleme zamanı türüne sahip değilse dynamic , öğe erişimi, dinamik aşırı yükleme çözümünün derleme zamanı denetimikonusunda açıklandığı gibi sınırlı bir derleme süresi denetimi yapar.If the primary_no_array_creation_expression does not have compile-time type dynamic, then the element access undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

Bir element_access primary_no_array_creation_expression bir array_type değeri ise, element_access bir dizi erişimdir (dizi erişimi).If the primary_no_array_creation_expression of an element_access is a value of an array_type, the element_access is an array access (Array access). Aksi takdirde primary_no_array_creation_expression , bir veya daha fazla Indexer üyesine sahip bir sınıf, yapı veya arabirim türünün bir değişkeni ya da değeri olmalıdır ve bu durumda element_access bir Dizin Oluşturucu erişimi (Dizin Oluşturucu erişimi) olur.Otherwise, the primary_no_array_creation_expression must be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the element_access is an indexer access (Indexer access).

Dizi erişimiArray access

Dizi erişimi için element_access primary_no_array_creation_expression bir array_type değeri olmalıdır.For an array access, the primary_no_array_creation_expression of the element_access must be a value of an array_type. Ayrıca, dizi erişiminin argument_list adlandırılmış bağımsız değişkenler içermesine izin verilmez. Argument_list ifadelerin sayısı, array_type derecesine göre aynı olmalıdır ve her ifadenin türü,,,, int uint long ulong veya bu türlerden birine veya daha fazlasına örtük olarak dönüştürülebilir olması gerekir.Furthermore, the argument_list of an array access is not allowed to contain named arguments.The number of expressions in the argument_list must be the same as the rank of the array_type, and each expression must be of type int, uint, long, ulong, or must be implicitly convertible to one or more of these types.

Dizi erişiminin hesaplanmasının sonucu, dizinin öğe türünün bir değişkenidir; Yani, argument_list ifade (ler) in değeri tarafından seçilen dizi öğesi.The result of evaluating an array access is a variable of the element type of the array, namely the array element selected by the value(s) of the expression(s) in the argument_list.

Formun bir dizi erişiminin çalışma zamanı işleme, P[A] burada bir P array_type primary_no_array_creation_expression ve A bir argument_list, aşağıdaki adımlardan oluşur:The run-time processing of an array access of the form P[A], where P is a primary_no_array_creation_expression of an array_type and A is an argument_list, consists of the following steps:

  • P değerlendirilir.P is evaluated. Bu değerlendirme bir özel duruma neden olursa başka bir adım yürütülmez.If this evaluation causes an exception, no further steps are executed.
  • Argument_list Dizin ifadeleri soldan sağa sırayla değerlendirilir.The index expressions of the argument_list are evaluated in order, from left to right. Her bir dizin ifadesinin değerlendirmesi aşağıdaki türlerden birine örtük dönüştürme (örtük dönüştürmeler) yapılır: int , uint , long , ulong .Following evaluation of each index expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. Bu listede örtük bir dönüştürmenin bulunduğu ilk tür seçilir.The first type in this list for which an implicit conversion exists is chosen. Örneğin, Dizin ifadesi tür ise, short int öğesinden short int ve öğesinden öğesine örtük dönüştürmeler short mümkün olduğundan örtük bir dönüştürme yapılır long .For instance, if the index expression is of type short then an implicit conversion to int is performed, since implicit conversions from short to int and from short to long are possible. Bir dizin ifadesi veya sonraki örtük dönüştürme değerlendirmesi bir özel duruma neden oluyorsa, daha fazla dizin ifadesi değerlendirilmez ve başka bir adım yürütülmez.If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed.
  • Öğesinin değeri P geçerli olacak şekilde işaretlendi.The value of P is checked to be valid. Değeri P ise null , bir System.NullReferenceException atılır ve başka bir adım yürütülmez.If the value of P is null, a System.NullReferenceException is thrown and no further steps are executed.
  • Argument_list her bir ifadenin değeri, tarafından başvurulan dizi örneğinin her boyutunun gerçek sınırlarına göre denetlenir P .The value of each expression in the argument_list is checked against the actual bounds of each dimension of the array instance referenced by P. Bir veya daha fazla değer Aralık dışında ise, bir System.IndexOutOfRangeException atılır ve başka bir adım yürütülmez.If one or more values are out of range, a System.IndexOutOfRangeException is thrown and no further steps are executed.
  • Dizin ifadeleri tarafından verilen dizi öğesinin konumu hesaplanır ve bu konum dizi erişiminin sonucu olur.The location of the array element given by the index expression(s) is computed, and this location becomes the result of the array access.

Dizin Oluşturucu erişimiIndexer access

Dizin Oluşturucu erişimi için, element_access primary_no_array_creation_expression bir sınıf , yapı veya arabirim türünde bir değişken ya da değer olmalıdır ve bu tür element_access argument_list açısından geçerli olan bir veya daha fazla Dizin Oluşturucu uygulamalıdır.For an indexer access, the primary_no_array_creation_expression of the element_access must be a variable or value of a class, struct, or interface type, and this type must implement one or more indexers that are applicable with respect to the argument_list of the element_access.

Formun bir Dizin Oluşturucu erişimi olan bağlama zamanı işleme, burada bir P[A] P sınıf, yapı veya arabirim türü primary_no_array_creation_expression T ve A bir argument_list, aşağıdaki adımlardan oluşur:The binding-time processing of an indexer access of the form P[A], where P is a primary_no_array_creation_expression of a class, struct, or interface type T, and A is an argument_list, consists of the following steps:

  • Tarafından sunulan Dizin oluşturucular kümesi T oluşturulur.The set of indexers provided by T is constructed. Küme, içinde belirtilen tüm dizin oluşturuculardan T ya da T override bildirim olmayan ve geçerli bağlamda erişilebilir olan (üye erişim) bir temel türünde oluşur.The set consists of all indexers declared in T or a base type of T that are not override declarations and are accessible in the current context (Member access).
  • Küme, uygulanabilir ve diğer Dizin oluşturucular tarafından gizlenmediği dizin oluşturucularının düşürüldü.The set is reduced to those indexers that are applicable and not hidden by other indexers. Aşağıdaki kurallar, içindeki dizin S.I oluşturucunun bildirildiği tür olan, küme içindeki her dizin oluşturucuya uygulanır S I :The following rules are applied to each indexer S.I in the set, where S is the type in which the indexer I is declared:
    • I A (Uygulanabilir işlev üyesi) öğesine göre geçerli değilse, I kümeden kaldırılır.If I is not applicable with respect to A (Applicable function member), then I is removed from the set.
    • I A (Uygulanabilir işlev üyesi) açısından geçerliyse, taban türünde belirtilen tüm dizin oluşturucular S kümeden kaldırılır.If I is applicable with respect to A (Applicable function member), then all indexers declared in a base type of S are removed from the set.
    • , I A (Uygulanabilir işlev üyesi) öğesine göre uygulanabilir ve dışında S bir sınıf türü ise object , bir arabirimde belirtilen tüm dizin oluşturucular kümeden kaldırılır.If I is applicable with respect to A (Applicable function member) and S is a class type other than object, all indexers declared in an interface are removed from the set.
  • Elde edilen aday Dizin oluşturucular kümesi boşsa, uygulanabilir Dizin oluşturucular yok ve bir bağlama zamanı hatası oluşur.If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs.
  • Aday Dizin oluşturucular kümesinin en iyi Dizin Oluşturucusu, aşırı yükleme çözümününaşırı yükleme çözümleme kuralları kullanılarak tanımlanır.The best indexer of the set of candidate indexers is identified using the overload resolution rules of Overload resolution. Tek bir en iyi Dizin Oluşturucu tanımlanamıyorsa, Dizin Oluşturucu erişimi belirsizdir ve bir bağlama zamanı hatası oluşur.If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs.
  • Argument_list Dizin ifadeleri soldan sağa sırayla değerlendirilir.The index expressions of the argument_list are evaluated in order, from left to right. Dizin Oluşturucu erişimini işlemenin sonucu, Dizin Oluşturucu erişimi olarak sınıflandırılan bir ifadedir.The result of processing the indexer access is an expression classified as an indexer access. Dizin Oluşturucu erişim ifadesi, yukarıdaki adımda belirlenen dizin oluşturucuya başvurur ve ilişkili bir örnek ifadesi P ve ilişkili bağımsız değişken listesi içerir A .The indexer access expression references the indexer determined in the step above, and has an associated instance expression of P and an associated argument list of A.

Bir Dizin Oluşturucu erişimi, kullanıldığı içeriğe bağlı olarak, dizin oluşturucunun Get erişimcisinin veya set erişimcisinin çağrısına neden olur.Depending on the context in which it is used, an indexer access causes invocation of either the get accessor or the set accessor of the indexer. Dizin Oluşturucu erişimi bir atamanın hedefi ise, küme erişimcisi yeni bir değer atamak için çağrılır (basit atama).If the indexer access is the target of an assignment, the set accessor is invoked to assign a new value (Simple assignment). Diğer tüm durumlarda, get erişimcisi geçerli değeri (ifadelerin değerleri) almak için çağrılır.In all other cases, the get accessor is invoked to obtain the current value (Values of expressions).

Bu erişimThis access

This_Access , ayrılmış sözcükten oluşur this .A this_access consists of the reserved word this.

this_access
    : 'this'
    ;

Bir This_Access yalnızca bir örnek oluşturucusunun, örnek yönteminin veya örnek erişimcinin bloğunda izin verilir.A this_access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. Aşağıdaki anlamlara sahiptir:It has one of the following meanings:

  • thisBir sınıfın örnek Oluşturucusu içindeki bir primary_expression kullanıldığında, bir değer olarak sınıflandırılmaktadır.When this is used in a primary_expression within an instance constructor of a class, it is classified as a value. Değerin türü, kullanımın gerçekleştiği sınıfın örnek türü (örnek türü) ve değer, oluşturulmakta olan nesneye bir başvurudur.The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object being constructed.
  • Bir this sınıfın örnek metodu veya örnek erişimcisi içindeki bir primary_expression kullanıldığında, bir değer olarak sınıflandırılmaktadır.When this is used in a primary_expression within an instance method or instance accessor of a class, it is classified as a value. Değerin türü, kullanımının gerçekleştiği sınıfın örnek türü (örnek türü) ve değer, yöntemin veya erişimcinin çağrıldığı nesneye bir başvurudur.The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object for which the method or accessor was invoked.
  • Bir this yapının örnek Oluşturucusu içindeki bir primary_expression kullanıldığında, değişken olarak sınıflandırılır.When this is used in a primary_expression within an instance constructor of a struct, it is classified as a variable. Değişkenin türü, kullanımın gerçekleştiği yapının örnek türüdür (örnek türü) ve değişken oluşturulan yapıyı temsil eder.The type of the variable is the instance type (The instance type) of the struct within which the usage occurs, and the variable represents the struct being constructed. thisBir yapının örnek oluşturucusunun değişkeni, yapı türünün bir parametresiyle tamamen aynı şekilde davranır out — özellikle bu, değişkenin örnek oluşturucusunun her yürütme yolunda kesinlikle atanması gerektiği anlamına gelir.The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor.
  • Bir this yapının örnek metodu veya örnek erişimcisi içindeki bir primary_expression kullanıldığında, bir değişken olarak sınıflandırılmaktadır.When this is used in a primary_expression within an instance method or instance accessor of a struct, it is classified as a variable. Değişkenin türü, kullanımının gerçekleştiği yapının örnek türüdür (örnek türü).The type of the variable is the instance type (The instance type) of the struct within which the usage occurs.
    • Yöntem veya erişimci bir yineleyici (yineleyiciler) değilse, this değişkeni Yöntem veya erişimcinin çağrıldığı yapıyı temsil eder ve ref yapı türünün parametresiyle tamamen aynı şekilde davranır.If the method or accessor is not an iterator (Iterators), the this variable represents the struct for which the method or accessor was invoked, and behaves exactly the same as a ref parameter of the struct type.
    • Yöntem veya erişimci bir yineleyici ise, this değişkeni yöntemi veya erişimcinin çağrıldığı yapının bir kopyasını temsil eder ve yapı türünün bir değer parametresiyle tam olarak aynı şekilde davranır.If the method or accessor is an iterator, the this variable represents a copy of the struct for which the method or accessor was invoked, and behaves exactly the same as a value parameter of the struct type.

thisYukarıda listelenenlerden farklı bir bağlamda primary_expression kullanımı, derleme zamanı hatasıdır.Use of this in a primary_expression in a context other than the ones listed above is a compile-time error. Özellikle, bir this statik yöntemde, statik bir özellik erişimcisinde veya bir alan bildiriminin variable_initializer başvuruda bulunmak mümkün değildir.In particular, it is not possible to refer to this in a static method, a static property accessor, or in a variable_initializer of a field declaration.

Temel erişimBase access

Base_access , ayrılmış sözcükten sonra base " . " belirteci ve tanımlayıcı ya da köşeli ayraç içine alınmış bir argument_list oluşur:A base_access consists of the reserved word base followed by either a "." token and an identifier or an argument_list enclosed in square brackets:

base_access
    : 'base' '.' identifier
    | 'base' '[' expression_list ']'
    ;

Geçerli sınıf veya yapıda benzer adlandırılmış Üyeler tarafından gizlenen temel sınıf üyelerine erişmek için bir base_access kullanılır.A base_access is used to access base class members that are hidden by similarly named members in the current class or struct. Bir base_access yalnızca bir örnek oluşturucusunun, örnek yönteminin veya örnek erişimcinin bloğunda izin verilir.A base_access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. base.IBir sınıf veya yapı biriminde oluştuğunda, I Bu sınıfın veya yapının temel sınıfının bir üyesini belirtmelidir.When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct. Benzer şekilde, base[E] bir sınıfta gerçekleştiğinde, temel sınıfta ilgili bir Dizin Oluşturucu bulunmalıdır.Likewise, when base[E] occurs in a class, an applicable indexer must exist in the base class.

Bağlama sırasında, form base_access ifadeleri base.I ve base[E] tam olarak yazıldığı gibi değerlendirilir ve ((B)this).I ((B)this)[E] burada, B yapının gerçekleştiği sınıfın veya yapının temel sınıfıdır.At binding-time, base_access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Bu nedenle, ve ' a base.I base[E] karşılık gelir, this.I this[E] ancak this temel sınıfın bir örneği olarak görüntülenir.Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.

Bir base_access bir sanal işlev üyesine (bir yöntem, özellik veya Dizin Oluşturucu) başvurduğunda, çalışma zamanında hangi işlev üyesinin çalıştırılacağını belirleme (dinamik aşırı yükleme çözümünün derleme zamanı denetimi) değiştirilir.When a base_access references a virtual function member (a method, property, or indexer), the determination of which function member to invoke at run-time (Compile-time checking of dynamic overload resolution) is changed. Çağrılan işlev üyesi, işlev üyesinin B (çalışma zamanı türü ' ne göre değil this , temel olmayan bir erişimde olduğu gibi) en çok türetilmiş uygulama (sanal yöntemler) ile belirlenir.The function member that is invoked is determined by finding the most derived implementation (Virtual methods) of the function member with respect to B (instead of with respect to the run-time type of this, as would be usual in a non-base access). Bu nedenle, bir override virtual işlev üyesinin içinde, işlev üyesinin devralınmış uygulamasını çağırmak için bir base_access kullanılabilir.Thus, within an override of a virtual function member, a base_access can be used to invoke the inherited implementation of the function member. Bir base_access tarafından başvurulan işlev üyesi Özet ise, bir bağlama zamanı hatası oluşur.If the function member referenced by a base_access is abstract, a binding-time error occurs.

Sonek artırma ve azaltma işleçleriPostfix increment and decrement operators

post_increment_expression
    : primary_expression '++'
    ;

post_decrement_expression
    : primary_expression '--'
    ;

Bir sonek artışı veya azaltma işleminin işleneni, değişken olarak sınıflandırılmış bir ifade, özellik erişimi veya Dizin Oluşturucu erişimi olmalıdır.The operand of a postfix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. İşlemin sonucu, işlenenden aynı türde bir değerdir.The result of the operation is a value of the same type as the operand.

Primary_expression derleme zamanı türüne sahipse, dynamic işleç dinamik olarak bağlanır (dinamik bağlama), post_increment_expression veya post_decrement_expression derleme zamanı türüne sahiptir dynamic ve primary_expression çalışma zamanı türü kullanılarak çalışma zamanında aşağıdaki kurallar uygulanır.If the primary_expression has the compile-time type dynamic then the operator is dynamically bound (Dynamic binding), the post_increment_expression or post_decrement_expression has the compile-time type dynamic and the following rules are applied at run-time using the run-time type of the primary_expression.

Bir sonek artışı veya azaltma işleminin işleneni bir özellik veya Dizin Oluşturucu erişimi ise, özelliğin veya dizin oluşturucunun hem a hem de erişimcisi olmalıdır get set .If the operand of a postfix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. Bu durumda, bir bağlama zamanı hatası oluşur.If this is not the case, a binding-time error occurs.

Tekil operatör aşırı yükleme çözümü (birli operatör aşırı yükleme çözünürlüğü) belirli bir operatör uygulamasını seçmek için uygulanır.Unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. ++ -- Şu türler için önceden tanımlanmış ve işleçler var: sbyte ,,,, byte short ushort int , uint , long , ulong , char , float , double , decimal ve herhangi bir numaralandırma türü.Predefined ++ and -- operators exist for the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, and any enum type. Önceden tanımlanmış ++ işleçler, işlenene 1 eklenerek üretilen değeri döndürür ve önceden tanımlanmış -- işleçler, işleneni 1 çıkararak üretilen değeri döndürür.The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined -- operators return the value produced by subtracting 1 from the operand. Bir checked bağlamda, bu ekleme veya çıkarma sonucunda elde edilen sonuç, sonuç türü aralığının dışındaysa ve sonuç türü bir integral türü ya da numaralandırma türüdür, bir oluşturulur System.OverflowException .In a checked context, if the result of this addition or subtraction is outside the range of the result type and the result type is an integral type or enum type, a System.OverflowException is thrown.

Formun sonek artırma veya azaltma işleminin çalışma zamanı işleme x++ veya x-- aşağıdaki adımlardan oluşur:The run-time processing of a postfix increment or decrement operation of the form x++ or x-- consists of the following steps:

  • xBir değişken olarak sınıflandırıldıysanız:If x is classified as a variable:
    • x değişkeni üretmek için değerlendirilir.x is evaluated to produce the variable.
    • Değeri x kaydedilir.The value of x is saved.
    • Seçilen işleç, kaydedilmiş değeri x bağımsız değişkeni olarak çağrılır.The selected operator is invoked with the saved value of x as its argument.
    • İşleci tarafından döndürülen değer, değerlendirmesi tarafından verilen konumda depolanır x .The value returned by the operator is stored in the location given by the evaluation of x.
    • Kaydedilen değeri x işlemin sonucu olur.The saved value of x becomes the result of the operation.
  • xÖzellik veya Dizin Oluşturucu erişimi olarak sınıflandırıldıysanız:If x is classified as a property or indexer access:
    • İle ilişkili örnek ifadesi (değilse x static ) ve bağımsız değişken listesi ( x bir Dizin Oluşturucu erişimsiyse) x değerlendirilir ve sonuçlar sonraki get ve set erişimci etkinleştirmeleri içinde kullanılır.The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
    • getErişimcisi x çağrılır ve döndürülen değer kaydedilir.The get accessor of x is invoked and the returned value is saved.
    • Seçilen işleç, kaydedilmiş değeri x bağımsız değişkeni olarak çağrılır.The selected operator is invoked with the saved value of x as its argument.
    • setErişimcisi, x bağımsız değişkeni olarak işleç tarafından döndürülen değerle çağrılır value .The set accessor of x is invoked with the value returned by the operator as its value argument.
    • Kaydedilen değeri x işlemin sonucu olur.The saved value of x becomes the result of the operation.

++Ve -- işleçleri de ön ek gösterimini (önek artırma ve azaltma işleçleri) destekler.The ++ and -- operators also support prefix notation (Prefix increment and decrement operators). Genellikle, x++ veya sonucu x-- x işlemin önünde değeri olur, ancak sonucu işlemden ++x --x x sonraki değeridir.Typically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. Her iki durumda da, x işlemden sonra aynı değere sahiptir.In either case, x itself has the same value after the operation.

operator ++Ya operator -- da bir uygulama, sonek veya ön ek gösterimi kullanılarak çağrılabilir.An operator ++ or operator -- implementation can be invoked using either postfix or prefix notation. İki gösterimler için ayrı işleç uygulamalarına sahip olmak mümkün değildir.It is not possible to have separate operator implementations for the two notations.

New işleciThe new operator

newİşleci, türlerin yeni örneklerini oluşturmak için kullanılır.The new operator is used to create new instances of types.

Üç ifade biçimi vardır new :There are three forms of new expressions:

  • Nesne oluşturma ifadeleri, sınıf türlerinin ve değer türlerinin yeni örneklerini oluşturmak için kullanılır.Object creation expressions are used to create new instances of class types and value types.
  • Dizi oluşturma ifadeleri dizi türlerinin yeni örneklerini oluşturmak için kullanılır.Array creation expressions are used to create new instances of array types.
  • Temsilci oluşturma ifadeleri temsilci türlerinin yeni örneklerini oluşturmak için kullanılır.Delegate creation expressions are used to create new instances of delegate types.

newİşleci bir tür örneğinin oluşturulmasını, ancak dinamik bellek ayırmayı göstermez.The new operator implies creation of an instance of a type, but does not necessarily imply dynamic allocation of memory. Özellikle, değer türlerinin örnekleri, bulundukları değişkenlerin ötesinde ek bellek gerektirmez ve new değer türlerinin örneklerini oluşturmak için kullanıldığında hiçbir dinamik ayırma gerçekleşmez.In particular, instances of value types require no additional memory beyond the variables in which they reside, and no dynamic allocations occur when new is used to create instances of value types.

Nesne oluşturma ifadeleriObject creation expressions

Bir object_creation_expression class_type veya value_type yeni bir örneğini oluşturmak için kullanılır.An object_creation_expression is used to create a new instance of a class_type or a value_type.

object_creation_expression
    : 'new' type '(' argument_list? ')' object_or_collection_initializer?
    | 'new' type object_or_collection_initializer
    ;

object_or_collection_initializer
    : object_initializer
    | collection_initializer
    ;

Object_creation_expression türü class_type, value_type veya type_parameter olmalıdır.The type of an object_creation_expression must be a class_type, a value_type or a type_parameter. Tür abstract class_type olamaz.The type cannot be an abstract class_type.

İsteğe bağlı argument_list (bağımsız değişken listeleri) yalnızca tür bir class_type veya struct_type olduğunda izin verilir.The optional argument_list (Argument lists) is permitted only if the type is a class_type or a struct_type.

Nesne oluşturma ifadesi, Oluşturucu bağımsız değişken listesini atlayabilir ve kapsayan parantez, bir nesne Başlatıcısı veya koleksiyon başlatıcısı içerir.An object creation expression can omit the constructor argument list and enclosing parentheses provided it includes an object initializer or collection initializer. Oluşturucu bağımsız değişken listesini atlama ve kapsayan parantezler boş bir bağımsız değişken listesi belirtmeye eşdeğerdir.Omitting the constructor argument list and enclosing parentheses is equivalent to specifying an empty argument list.

Bir nesne Başlatıcısı veya koleksiyon başlatıcısı içeren bir nesne oluşturma ifadesinin işlenmesi, ilk örnek oluşturucuyu işlemeyi ve ardından nesne Başlatıcısı (nesne başlatıcıları) veya koleksiyon başlatıcısı (koleksiyon başlatıcıları) tarafından belirtilen üye veya öğe başlatmaları işlemeyi içerir.Processing of an object creation expression that includes an object initializer or collection initializer consists of first processing the instance constructor and then processing the member or element initializations specified by the object initializer (Object initializers) or collection initializer (Collection initializers).

İsteğe bağlı argument_list bağımsız değişkenlerden herhangi birinin derleme zamanı türü varsa, dynamic object_creation_expression dinamik olarak bağlanır (dinamik bağlama) ve aşağıdaki kurallar, derleme zamanı türüne sahip argument_list bağımsız değişkenlerinin çalışma zamanı türü kullanılarak çalışma zamanında uygulanır dynamic .If any of the arguments in the optional argument_list has the compile-time type dynamic then the object_creation_expression is dynamically bound (Dynamic binding) and the following rules are applied at run-time using the run-time type of those arguments of the argument_list that have the compile time type dynamic. Ancak, nesne oluşturma, dinamik aşırı yükleme çözümünün derleme zamanı denetimikonusunda açıklandığı gibi sınırlı bir derleme süresi denetimi yapar.However, the object creation undergoes a limited compile time check as described in Compile-time checking of dynamic overload resolution.

Formun object_creation_expression bağlama zamanı işleme new T(A) , burada T bir class_type veya value_type ve A isteğe bağlı bir argument_list, aşağıdaki adımlardan oluşur:The binding-time processing of an object_creation_expression of the form new T(A), where T is a class_type or a value_type and A is an optional argument_list, consists of the following steps:

  • TBir value_type ve yoksa A :If T is a value_type and A is not present:
    • Object_creation_expression varsayılan Oluşturucu çağrıdır.The object_creation_expression is a default constructor invocation. Object_creation_expression sonucu, T , T System. ValueType türündetanımlanan varsayılan değer olan türünde bir değerdir.The result of the object_creation_expression is a value of type T, namely the default value for T as defined in The System.ValueType type.
  • Aksi takdirde, T bir type_parameter ve yoksa A :Otherwise, if T is a type_parameter and A is not present:
    • İçin bir değer türü kısıtlaması veya Oluşturucu kısıtlaması (tür parametresi kısıtlamaları) belirtilmemişse T , bir bağlama zamanı hatası oluşur.If no value type constraint or constructor constraint (Type parameter constraints) has been specified for T, a binding-time error occurs.
    • Object_creation_expression sonucu, tür parametresinin bağlandığı çalışma zamanı türünün bir değeridir, yani bu türün varsayılan yapıcısını çağırma sonucu.The result of the object_creation_expression is a value of the run-time type that the type parameter has been bound to, namely the result of invoking the default constructor of that type. Çalışma zamanı türü bir başvuru türü veya değer türü olabilir.The run-time type may be a reference type or a value type.
  • Aksi takdirde, T bir class_type veya struct_type ise:Otherwise, if T is a class_type or a struct_type:
    • TBir abstract class_type, derleme zamanı hatası oluşur.If T is an abstract class_type, a compile-time error occurs.
    • Çağrılacak örnek Oluşturucu aşırı yükleme çözümününaşırı yükleme çözümleme kuralları kullanılarak belirlenir.The instance constructor to invoke is determined using the overload resolution rules of Overload resolution. Aday örnek oluşturucular kümesi, içinde belirtilen tüm erişilebilir örnek oluşturuculardan oluşur T A (uygulanabilir işlev üyesi).The set of candidate instance constructors consists of all accessible instance constructors declared in T which are applicable with respect to A (Applicable function member). Aday örnek oluşturucular kümesi boşsa veya tek bir en iyi örnek Oluşturucu tanımlanamıyorsa, bir bağlama zamanı hatası oluşur.If the set of candidate instance constructors is empty, or if a single best instance constructor cannot be identified, a binding-time error occurs.
    • Object_creation_expression sonucu, T Yukarıdaki adımda belirlenen örnek Oluşturucu çağrılarak oluşturulan değer olan türünde bir değerdir.The result of the object_creation_expression is a value of type T, namely the value produced by invoking the instance constructor determined in the step above.
  • Aksi takdirde, object_creation_expression geçersizdir ve bir bağlama zamanı hatası oluşur.Otherwise, the object_creation_expression is invalid, and a binding-time error occurs.

Object_creation_expression dinamik olarak bağlı olsa da, derleme zamanı türü yine de vardır T .Even if the object_creation_expression is dynamically bound, the compile-time type is still T.

Formun object_creation_expression çalışma zamanı işleme new T(A) , burada T class_type veya struct_type ve A isteğe bağlı bir argument_list, aşağıdaki adımlardan oluşur:The run-time processing of an object_creation_expression of the form new T(A), where T is class_type or a struct_type and A is an optional argument_list, consists of the following steps:

  • TBir class_type ise:If T is a class_type:
    • Sınıfının yeni bir örneği T ayrıldı.A new instance of class T is allocated. Yeni örneği ayırmak için yeterli kullanılabilir bellek yoksa, bir System.OutOfMemoryException oluşturulur ve başka bir adım yürütülmez.If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
    • Yeni örneğin tüm alanları varsayılan değerlerine (varsayılan değerler) başlatılır.All fields of the new instance are initialized to their default values (Default values).
    • Örnek Oluşturucu, işlev üye çağırma kurallarına göre çağrılır (dinamik aşırı yükleme çözümünün derleme zamanı denetimi).The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). Yeni ayrılmış örneğe bir başvuru, örnek oluşturucusuna otomatik olarak geçirilir ve örneğe Bu Oluşturucu içinden olarak erişilebilir this .A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.
  • TBir struct_type ise:If T is a struct_type:
    • Türünde bir örnek T , geçici bir yerel değişken ayırarak oluşturulur.An instance of type T is created by allocating a temporary local variable. Bir struct_type örnek Oluşturucusu oluşturulan örneğin her bir alanına kesinlikle değer atamak gerektiğinden, geçici değişkenin başlatılması gerekmez.Since an instance constructor of a struct_type is required to definitely assign a value to each field of the instance being created, no initialization of the temporary variable is necessary.
    • Örnek Oluşturucu, işlev üye çağırma kurallarına göre çağrılır (dinamik aşırı yükleme çözümünün derleme zamanı denetimi).The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). Yeni ayrılmış örneğe bir başvuru, örnek oluşturucusuna otomatik olarak geçirilir ve örneğe Bu Oluşturucu içinden olarak erişilebilir this .A reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.

Nesne başlatıcılarıObject initializers

Bir nesne Başlatıcısı , bir nesnenin sıfır veya daha fazla alanı, özelliği veya dizinli öğeleri için değerler belirtir.An object initializer specifies values for zero or more fields, properties or indexed elements of an object.

object_initializer
    : '{' member_initializer_list? '}'
    | '{' member_initializer_list ',' '}'
    ;

member_initializer_list
    : member_initializer (',' member_initializer)*
    ;

member_initializer
    : initializer_target '=' initializer_value
    ;

initializer_target
    : identifier
    | '[' argument_list ']'
    ;

initializer_value
    : expression
    | object_or_collection_initializer
    ;

Bir nesne Başlatıcısı, { ve belirteçleri içine alınmış ve virgülle ayrılmış bir dizi üye başlatıcıdan oluşur } .An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas. Her bir member_initializer başlatma için bir hedef belirler.Each member_initializer designates a target for the initialization. Bir tanımlayıcı , başlatılan nesnenin erişilebilir bir alanı veya özelliğini sağlamalıdır, ancak köşeli ayraç içine alınmış bir argument_list , başlatılan nesnede erişilebilir bir Dizin Oluşturucu için bağımsız değişkenler belirtmelidir.An identifier must name an accessible field or property of the object being initialized, whereas an argument_list enclosed in square brackets must specify arguments for an accessible indexer on the object being initialized. Bir nesne başlatıcısının aynı alan veya özellik için birden fazla üye başlatıcısı içermesi hatadır.It is an error for an object initializer to include more than one member initializer for the same field or property.

Her initializer_target ardından bir eşittir işareti ve bir ifade, bir nesne Başlatıcısı veya bir koleksiyon başlatıcısı gelir.Each initializer_target is followed by an equals sign and either an expression, an object initializer or a collection initializer. Nesne Başlatıcısı içindeki ifadeler, başlatılan yeni oluşturulan nesneye başvuracaktır.It is not possible for expressions within the object initializer to refer to the newly created object it is initializing.

Eşittir işaretinden sonra bir ifade belirten bir üye başlatıcısı, hedefle (basit atama) aynı şekilde işlenir.A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment (Simple assignment) to the target.

Eşittir işaretinden sonra bir nesne Başlatıcısı belirten bir üye başlatıcısı, iç içe geçmiş nesne Başlatıcısı, yani gömülü bir nesnenin bir başlatması.A member initializer that specifies an object initializer after the equals sign is a nested object initializer, i.e. an initialization of an embedded object. Alan veya özelliğe yeni bir değer atamak yerine, iç içe nesne başlatıcısındaki atamalar, alan veya özellik üyelerine atamalar olarak değerlendirilir.Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. İç içe nesne başlatıcıları bir değer türü olan özelliklere veya bir değer türüne sahip salt okuma alanlarına uygulanamaz.Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type.

Eşittir işaretinden sonra bir koleksiyon başlatıcısı belirten üye başlatıcısı, gömülü bir koleksiyonun başlatılmasından.A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. Hedef alana, özelliğe veya dizin oluşturucuya yeni bir koleksiyon atamak yerine, başlatıcıda verilen öğeler hedef tarafından başvurulan koleksiyona eklenir.Instead of assigning a new collection to the target field, property or indexer, the elements given in the initializer are added to the collection referenced by the target. Hedef, koleksiyon başlatıcıları'nda belirtilen gereksinimleri karşılayan bir koleksiyon türünde olmalıdır.The target must be of a collection type that satisfies the requirements specified in Collection initializers.

Bir dizin başlatıcısının bağımsız değişkenleri her zaman tam olarak bir kez değerlendirilir.The arguments to an index initializer will always be evaluated exactly once. Bu nedenle, bağımsız değişkenler (örneğin, boş bir iç içe bir başlatıcı nedeniyle) hiç kullanılmasa bile, bunların yan etkileri için değerlendirilirler.Thus, even if the arguments end up never getting used (e.g. because of an empty nested initializer), they will be evaluated for their side effects.

Aşağıdaki sınıf iki koordinat içeren bir noktayı temsil eder:The following class represents a point with two coordinates:

public class Point
{
    int x, y;

    public int X { get { return x; } set { x = value; } }
    public int Y { get { return y; } set { y = value; } }
}

Bir örneği Point aşağıdaki şekilde oluşturulup başlatılabilir:An instance of Point can be created and initialized as follows:

Point a = new Point { X = 0, Y = 1 };

aynı etkiye sahipwhich has the same effect as

Point __a = new Point();
__a.X = 0;
__a.Y = 1; 
Point a = __a;

__aAksi halde görünmeyen ve erişilemeyen geçici değişken.where __a is an otherwise invisible and inaccessible temporary variable. Aşağıdaki sınıf, iki noktadan oluşturulan bir dikdörtgeni temsil eder:The following class represents a rectangle created from two points:

public class Rectangle
{
    Point p1, p2;

    public Point P1 { get { return p1; } set { p1 = value; } }
    public Point P2 { get { return p2; } set { p2 = value; } }
}

Bir örneği Rectangle aşağıdaki şekilde oluşturulup başlatılabilir:An instance of Rectangle can be created and initialized as follows:

Rectangle r = new Rectangle {
    P1 = new Point { X = 0, Y = 1 },
    P2 = new Point { X = 2, Y = 3 }
};

aynı etkiye sahipwhich has the same effect as

Rectangle __r = new Rectangle();
Point __p1 = new Point();
__p1.X = 0;
__p1.Y = 1;
__r.P1 = __p1;
Point __p2 = new Point();
__p2.X = 2;
__p2.Y = 3;
__r.P2 = __p2; 
Rectangle r = __r;

__r __p1 ve __p2 Aksi durumda görünmez ve erişilemeyen geçici değişkenlerdir.where __r, __p1 and __p2 are temporary variables that are otherwise invisible and inaccessible.

Eğer Rectangle Oluşturucusu iki katıştırılmış Point örneği ayırırIf Rectangle's constructor allocates the two embedded Point instances

public class Rectangle
{
    Point p1 = new Point();
    Point p2 = new Point();

    public Point P1 { get { return p1; } }
    public Point P2 { get { return p2; } }
}

Aşağıdaki yapı, Point yeni örnekleri atamak yerine katıştırılmış örnekleri başlatmak için kullanılabilir:the following construct can be used to initialize the embedded Point instances instead of assigning new instances:

Rectangle r = new Rectangle {
    P1 = { X = 0, Y = 1 },
    P2 = { X = 2, Y = 3 }
};

aynı etkiye sahipwhich has the same effect as

Rectangle __r = new Rectangle();
__r.P1.X = 0;
__r.P1.Y = 1;
__r.P2.X = 2;
__r.P2.Y = 3;
Rectangle r = __r;

C 'nin uygun bir tanımı verildiğinde aşağıdaki örnek:Given an appropriate definition of C, the following example:

var c = new C {
    x = true,
    y = { a = "Hello" },
    z = { 1, 2, 3 },
    ["x"] = 5,
    [0,0] = { "a", "b" },
    [1,2] = {}
};

Bu atama dizisine eşdeğerdir:is equivalent to this series of assignments:

C __c = new C();
__c.x = true;
__c.y.a = "Hello";
__c.z.Add(1); 
__c.z.Add(2);
__c.z.Add(3);
string __i1 = "x";
__c[__i1] = 5;
int __i2 = 0, __i3 = 0;
__c[__i2,__i3].Add("a");
__c[__i2,__i3].Add("b");
int __i4 = 1, __i5 = 2;
var c = __c;

Burada __c , vb., görünmeyen ve kaynak kodla erişilemeyen değişkenler oluşturulur.where __c, etc., are generated variables that are invisible and inaccessible to the source code. Bağımsız değişkenlerinin [0,0] yalnızca bir kez değerlendirileceğini ve için bağımsız değişkenlerin [1,2] hiç kullanılmasa bile bir kez değerlendirildiğini unutmayın.Note that the arguments for [0,0] are evaluated only once, and the arguments for [1,2] are evaluated once even though they are never used.

Koleksiyon başlatıcılarıCollection initializers

Koleksiyon Başlatıcısı, bir koleksiyonun öğelerini belirtir.A collection initializer specifies the elements of a collection.

collection_initializer
    : '{' element_initializer_list '}'
    | '{' element_initializer_list ',' '}'
    ;

element_initializer_list
    : element_initializer (',' element_initializer)*
    ;

element_initializer
    : non_assignment_expression
    | '{' expression_list '}'
    ;

expression_list
    : expression (',' expression)*
    ;

Koleksiyon Başlatıcısı, { ve belirteçleri içine alınmış ve virgülle ayrılmış bir dizi öğe başlatıcısından oluşur } .A collection initializer consists of a sequence of element initializers, enclosed by { and } tokens and separated by commas. Her öğe başlatıcısı, başlatılmakta olan koleksiyon nesnesine eklenecek bir öğe belirtir ve ve { belirteçleri kapsayan ve virgüllerle ayrılmış bir ifade listesinden oluşur } .Each element initializer specifies an element to be added to the collection object being initialized, and consists of a list of expressions enclosed by { and } tokens and separated by commas. Tek ifadeyle bir öğe başlatıcısı küme ayracı olmadan yazılabilir, ancak üye başlatıcılarla belirsizliğe engel olmak için atama ifadesi olamaz.A single-expression element initializer can be written without braces, but cannot then be an assignment expression, to avoid ambiguity with member initializers. Non_assignment_expression üretimi ifadedetanımlanmıştır.The non_assignment_expression production is defined in Expression.

Aşağıda, bir koleksiyon başlatıcısı içeren bir nesne oluşturma ifadesine örnek verilmiştir:The following is an example of an object creation expression that includes a collection initializer:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

Koleksiyon başlatıcısının uygulandığı koleksiyon nesnesi, uygulayan bir tür System.Collections.IEnumerable veya derleme zamanı hatası oluşuyor olmalıdır.The collection object to which a collection initializer is applied must be of a type that implements System.Collections.IEnumerable or a compile-time error occurs. Koleksiyon Başlatıcısı, belirtilen her bir öğe için Add bağımsız değişken listesi olarak öğe başlatıcısının ifade listesini, her bir çağrı için normal üye arama ve aşırı yükleme çözümlemesi uygulayarak hedef nesnede bir yöntemi çağırır.For each specified element in order, the collection initializer invokes an Add method on the target object with the expression list of the element initializer as argument list, applying normal member lookup and overload resolution for each invocation. Bu nedenle, koleksiyon nesnesinin her öğe başlatıcısı adına sahip geçerli bir örnek veya genişletme yöntemi olmalıdır Add .Thus, the collection object must have an applicable instance or extension method with the name Add for each element initializer.

Aşağıdaki sınıf, bir kişinin adını ve telefon numaralarının listesini temsil eder:The following class represents a contact with a name and a list of phone numbers:

public class Contact
{
    string name;
    List<string> phoneNumbers = new List<string>();

    public string Name { get { return name; } set { name = value; } }

    public List<string> PhoneNumbers { get { return phoneNumbers; } }
}

Bir List<Contact> , aşağıdaki şekilde oluşturulup başlatılabilir:A List<Contact> can be created and initialized as follows:

var contacts = new List<Contact> {
    new Contact {
        Name = "Chris Smith",
        PhoneNumbers = { "206-555-0101", "425-882-8080" }
    },
    new Contact {
        Name = "Bob Harris",
        PhoneNumbers = { "650-555-0199" }
    }
};

aynı etkiye sahipwhich has the same effect as

var __clist = new List<Contact>();
Contact __c1 = new Contact();
__c1.Name = "Chris Smith";
__c1.PhoneNumbers.Add("206-555-0101");
__c1.PhoneNumbers.Add("425-882-8080");
__clist.Add(__c1);
Contact __c2 = new Contact();
__c2.Name = "Bob Harris";
__c2.PhoneNumbers.Add("650-555-0199");
__clist.Add(__c2);
var contacts = __clist;

__clist __c1 ve __c2 Aksi durumda görünmez ve erişilemeyen geçici değişkenlerdir.where __clist, __c1 and __c2 are temporary variables that are otherwise invisible and inaccessible.

Dizi oluşturma ifadeleriArray creation expressions

Bir array_creation_expression array_type yeni bir örneğini oluşturmak için kullanılır.An array_creation_expression is used to create a new instance of an array_type.

array_creation_expression
    : 'new' non_array_type '[' expression_list ']' rank_specifier* array_initializer?
    | 'new' array_type array_initializer
    | 'new' rank_specifier array_initializer
    ;

İlk formun dizi oluşturma ifadesi, bağımsız ifadelerin her birini ifade listesinden silmenin sonucu olan türün bir dizi örneğini ayırır.An array creation expression of the first form allocates an array instance of the type that results from deleting each of the individual expressions from the expression list. Örneğin, dizi oluşturma ifadesi new int[10,20] türünde bir dizi örneği üretir int[,] ve dizi oluşturma ifadesi new int[10][,] türünde bir dizi üretir int[][,] .For example, the array creation expression new int[10,20] produces an array instance of type int[,], and the array creation expression new int[10][,] produces an array of type int[][,]. İfade listesindeki her bir ifade,,, veya türünde int olmalıdır uint long ya da ulong Bu türlerden bir veya daha fazlasına örtülü olarak dönüştürülebilir olmalıdır.Each expression in the expression list must be of type int, uint, long, or ulong, or implicitly convertible to one or more of these types. Her ifadenin değeri, yeni ayrılan dizi örneğindeki karşılık gelen boyutun uzunluğunu belirler.The value of each expression determines the length of the corresponding dimension in the newly allocated array instance. Bir dizi boyutunun uzunluğunun negatif olması gerektiğinden, ifade listesinde negatif bir değer olan constant_expression bir derleme zamanı hatası olur.Since the length of an array dimension must be nonnegative, it is a compile-time error to have a constant_expression with a negative value in the expression list.

Güvenli olmayan bir bağlam (güvenli olmayan bağlamların) dışında, dizilerin düzeni belirtilmemiş olur.Except in an unsafe context (Unsafe contexts), the layout of arrays is unspecified.

İlk formun dizi oluşturma ifadesi bir dizi başlatıcısı içeriyorsa, ifade listesindeki her bir ifade bir sabit olmalıdır ve ifade listesi tarafından belirtilen sıralama ve boyut uzunlukları dizi başlatıcısının ile aynı olmalıdır.If an array creation expression of the first form includes an array initializer, each expression in the expression list must be a constant and the rank and dimension lengths specified by the expression list must match those of the array initializer.

İkinci veya üçüncü formun dizi oluşturma ifadesinde, belirtilen dizi türü veya sıralama belirticisinin sıralaması dizi başlatıcısının ile aynı olmalıdır.In an array creation expression of the second or third form, the rank of the specified array type or rank specifier must match that of the array initializer. Tek tek boyut uzunlukları, dizi başlatıcısının karşılık gelen iç içe geçme düzeylerindeki öğelerin sayısından algılanır.The individual dimension lengths are inferred from the number of elements in each of the corresponding nesting levels of the array initializer. Bu nedenle, ifadesiThus, the expression

new int[,] {{0, 1}, {2, 3}, {4, 5}}

tam olarak karşılık gelenexactly corresponds to

new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}

Üçüncü formun dizi oluşturma ifadesi, *örtülü olarak yazılmış dizi oluşturma ifadesi _ olarak adlandırılır.An array creation expression of the third form is referred to as an *implicitly typed array creation expression _. Dizinin öğe türü açıkça verilmemiştir, ancak dizi başlatıcısındaki ifadelerin kümesinin en iyi ortak türü (bir ifade kümesinin en iyi ortak türünü bulma) olarak belirlenir, ikinci forma benzerdir.It is similar to the second form, except that the element type of the array is not explicitly given, but determined as the best common type (Finding the best common type of a set of expressions) of the set of expressions in the array initializer. Çok boyutlu bir dizi için, örneğin, _rank_specifier * en az bir virgül içerdiğinde, bu küme iç içe array_initializer s ' de bulunan tüm ifade öğeleri içerir.For a multidimensional array, i.e., one where the _rank_specifier* contains at least one comma, this set comprises all expression s found in nested array_initializer s.

Dizi başlatıcıları, dizi başlatıcılardadaha ayrıntılı olarak açıklanmıştır.Array initializers are described further in Array initializers.

Dizi oluşturma ifadesinin değerlendirilme sonucu bir değer olarak sınıflandırıldığından, yani yeni ayrılmış dizi örneğine bir başvurudur.The result of evaluating an array creation expression is classified as a value, namely a reference to the newly allocated array instance. Bir dizi oluşturma ifadesinin çalışma zamanı işleme aşağıdaki adımlardan oluşur:The run-time processing of an array creation expression consists of the following steps:

  • Expression_list boyut uzunluğu ifadeleri, soldan sağa doğru sırayla değerlendirilir.The dimension length expressions of the expression_list are evaluated in order, from left to right. Her bir ifadenin aşağıdaki türlerden birine yönelik olarak, örtük bir dönüştürme (örtük dönüştürmeler),,,, int uint long ulong .Following evaluation of each expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. Bu listede örtük bir dönüştürmenin bulunduğu ilk tür seçilir.The first type in this list for which an implicit conversion exists is chosen. Bir ifade veya sonraki örtük dönüştürme değerlendirmesi bir özel duruma neden oluyorsa, başka ifadeler değerlendirilmez ve başka bir adım yürütülmez.If evaluation of an expression or the subsequent implicit conversion causes an exception, then no further expressions are evaluated and no further steps are executed.
  • Boyut uzunlukları için hesaplanan değerler aşağıdaki şekilde onaylanır.The computed values for the dimension lengths are validated as follows. Bir veya daha fazla değer sıfırdan küçükse, bir System.OverflowException atılır ve başka bir adım yürütülmez.If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.
  • Verilen boyut uzunluklarına sahip bir dizi örneği ayrıldı.An array instance with the given dimension lengths is allocated. Yeni örneği ayırmak için yeterli kullanılabilir bellek yoksa, bir System.OutOfMemoryException oluşturulur ve başka bir adım yürütülmez.If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
  • Yeni dizi örneğinin tüm öğeleri varsayılan değerlerine (varsayılan değerler) başlatılır.All elements of the new array instance are initialized to their default values (Default values).
  • Dizi oluşturma ifadesi bir dizi başlatıcısı içeriyorsa, dizi başlatıcısındaki her bir ifade değerlendirilir ve karşılık gelen dizi öğesine atanır.If the array creation expression contains an array initializer, then each expression in the array initializer is evaluated and assigned to its corresponding array element. Değerlendirmeler ve Atamalar, ifadelerin dizi başlatıcıda yazıldığı sırada gerçekleştirilir — diğer bir deyişle, öğeler, en sağdaki boyut ilk artarak Dizin sırasında başlatılır.The evaluations and assignments are performed in the order the expressions are written in the array initializer—in other words, elements are initialized in increasing index order, with the rightmost dimension increasing first. Belirli bir ifadenin değerlendirilmesi veya karşılık gelen dizi öğesine sonraki atama bir özel duruma neden oluyorsa, daha fazla öğe başlatılmaz (ve kalan öğelerin varsayılan değerleri olur).If evaluation of a given expression or the subsequent assignment to the corresponding array element causes an exception, then no further elements are initialized (and the remaining elements will thus have their default values).

Dizi oluşturma ifadesi bir dizi türünün öğeleriyle bir dizinin örneklemesine izin verir, ancak bu tür bir dizinin öğeleri el ile başlatılmış olmalıdır.An array creation expression permits instantiation of an array with elements of an array type, but the elements of such an array must be manually initialized. Örneğin, ekstresiFor example, the statement

int[][] a = new int[100][];

türünde 100 öğeleriyle tek boyutlu bir dizi oluşturur int[] .creates a single-dimensional array with 100 elements of type int[]. Her öğenin başlangıç değeri null .The initial value of each element is null. Aynı dizi oluşturma ifadesinin alt dizileri ve deyimi de örneği oluşturması mümkün değildirIt is not possible for the same array creation expression to also instantiate the sub-arrays, and the statement

int[][] a = new int[100][5];        // Error

derleme zamanı hatasına neden olur.results in a compile-time error. Alt dizilerin örneklenmesi bunun yerine el ile gerçekleştirilmelidir, örneğinInstantiation of the sub-arrays must instead be performed manually, as in

int[][] a = new int[100][];
for (int i = 0; i < 100; i++) a[i] = new int[5];

Dizi dizisinde "dikdörtgen" bir şekil varsa, bu, alt diziler aynı uzunluktadır ve çok boyutlu bir dizi kullanmak daha verimlidir.When an array of arrays has a "rectangular" shape, that is when the sub-arrays are all of the same length, it is more efficient to use a multi-dimensional array. Yukarıdaki örnekte, dizi dizisinin örneklenmesi 101 nesne oluşturuyor — bir dış dizi ve 100 alt dizileri.In the example above, instantiation of the array of arrays creates 101 objects—one outer array and 100 sub-arrays. Buna karşılık,In contrast,

int[,] = new int[100, 5];

yalnızca tek bir nesne, iki boyutlu bir dizi oluşturur ve ayırmayı tek bir ifadede gerçekleştirir.creates only a single object, a two-dimensional array, and accomplishes the allocation in a single statement.

Aşağıda örtük olarak yazılmış dizi oluşturma ifadelerinin örnekleri verilmiştir:The following are examples of implicitly typed array creation expressions:

var a = new[] { 1, 10, 100, 1000 };                       // int[]

var b = new[] { 1, 1.5, 2, 2.5 };                         // double[]

var c = new[,] { { "hello", null }, { "world", "!" } };   // string[,]

var d = new[] { 1, "one", 2, "two" };                     // Error

Son ifade, hiçbir ne de örtük olarak birbirlerine dönüştürülemediğinden derleme zamanı hatasına neden olur int string ve bu nedenle en iyi ortak tür yoktur.The last expression causes a compile-time error because neither int nor string is implicitly convertible to the other, and so there is no best common type. Açıkça yazılmış bir dizi oluşturma ifadesi bu durumda kullanılmalıdır, örneğin türünü belirtmek için object[] .An explicitly typed array creation expression must be used in this case, for example specifying the type to be object[]. Alternatif olarak, öğelerinden biri ortak bir temel türe alınabilir, bu da çıkarılan öğe türü olur.Alternatively, one of the elements can be cast to a common base type, which would then become the inferred element type.

Anonim olarak belirlenmiş veri yapıları oluşturmak için örtük olarak yazılmış dizi oluşturma ifadeleri anonim nesne başlatıcıları (anonim nesne oluşturma ifadeleri) ile birleştirilebilir.Implicitly typed array creation expressions can be combined with anonymous object initializers (Anonymous object creation expressions) to create anonymously typed data structures. Örnek:For example:

var contacts = new[] {
    new {
        Name = "Chris Smith",
        PhoneNumbers = new[] { "206-555-0101", "425-882-8080" }
    },
    new {
        Name = "Bob Harris",
        PhoneNumbers = new[] { "650-555-0199" }
    }
};

Temsilci oluşturma ifadeleriDelegate creation expressions

Bir delegate_creation_expression delegate_type yeni bir örneğini oluşturmak için kullanılır.A delegate_creation_expression is used to create a new instance of a delegate_type.

delegate_creation_expression
    : 'new' delegate_type '(' expression ')'
    ;

Bir temsilci oluşturma ifadesinin bağımsız değişkeni bir yöntem grubu, anonim bir işlev veya derleme zamanı türü dynamic ya da bir delegate_type değeri olmalıdır.The argument of a delegate creation expression must be a method group, an anonymous function or a value of either the compile time type dynamic or a delegate_type. Bağımsız değişken bir yöntem grubu ise, yöntemini ve bir örnek yöntemi için, bir temsilci oluşturulacak nesneyi tanımlar.If the argument is a method group, it identifies the method and, for an instance method, the object for which to create a delegate. Bağımsız değişken anonim bir işlevse, temsilci hedefinin parametrelerini ve Yöntem gövdesini doğrudan tanımlar.If the argument is an anonymous function it directly defines the parameters and method body of the delegate target. Bağımsız değişken bir değer ise, bir kopyasını oluşturmak için bir temsilci örneğini tanımlar.If the argument is a value it identifies a delegate instance of which to create a copy.

İfadede derleme zamanı türü varsa dynamic , delegate_creation_expression dinamik olarak bağlanır (dinamik bağlama) ve aşağıdaki kurallar, ifadenin çalışma zamanı türü kullanılarak çalışma zamanında uygulanır.If the expression has the compile-time type dynamic, the delegate_creation_expression is dynamically bound (Dynamic binding), and the rules below are applied at run-time using the run-time type of the expression. Aksi takdirde kurallar derleme zamanında uygulanır.Otherwise the rules are applied at compile-time.

Form delegate_creation_expression bağlama zamanı işleme new D(E) , burada D bir delegate_type ve E bir ifadedir, aşağıdaki adımlardan oluşur:The binding-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:

  • EBir yöntem grubsiyse, temsilci oluşturma ifadesi, bir yöntem grubu dönüştürmesi (Yöntem grubu dönüştürmeleri) ile arasında aynı şekilde işlenir E D .If E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
  • EAnonim bir işlevse, temsilci oluşturma ifadesi, anonim işlev dönüştürmesinin (anonim işlev dönüştürmeleri) ile arasında aynı şekilde işlenir E D .If E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
  • EBir değer ise, E ile uyumlu olmalıdır (temsilci bildirimleri) ve sonuç, ile D D aynı çağırma listesine başvuran yeni oluşturulmuş bir temsilciye başvurudur E .If E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. Eİle uyumlu değilse D , bir derleme zamanı hatası oluşur.If E is not compatible with D, a compile-time error occurs.

Formun delegate_creation_expression çalışma zamanı işleme new D(E) , burada D bir delegate_type ve E bir ifadedir, aşağıdaki adımlardan oluşur:The run-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:

  • EBir yöntem grubisiyse, temsilci oluşturma ifadesi ' dan ' a bir yöntem grubu dönüştürmesi (Yöntem grubu dönüştürmeleri) olarak E değerlendirilir D .If E is a method group, the delegate creation expression is evaluated as a method group conversion (Method group conversions) from E to D.
  • EAnonim bir işlevse, temsilci oluşturma ' dan E D (anonim işlev dönüştürmeleri) bir anonim işlev dönüştürmesi olarak değerlendirilir.If E is an anonymous function, the delegate creation is evaluated as an anonymous function conversion from E to D (Anonymous function conversions).
  • E Delegate_type bir değer ise:If E is a value of a delegate_type:
    • E değerlendirilir.E is evaluated. Bu değerlendirme bir özel duruma neden olursa başka bir adım yürütülmez.If this evaluation causes an exception, no further steps are executed.
    • Değeri E ise null , bir System.NullReferenceException atılır ve başka bir adım yürütülmez.If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
    • Temsilci türünün yeni bir örneği D ayrıldı.A new instance of the delegate type D is allocated. Yeni örneği ayırmak için yeterli kullanılabilir bellek yoksa, bir System.OutOfMemoryException oluşturulur ve başka bir adım yürütülmez.If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
    • Yeni temsilci örneği, tarafından verilen temsilci örneğiyle aynı çağırma listesiyle başlatılır E .The new delegate instance is initialized with the same invocation list as the delegate instance given by E.

Temsilcinin çağırma listesi, temsilcinin örneklendiği zaman belirlenir ve sonra temsilcinin tüm ömrü boyunca sabit kalır.The invocation list of a delegate is determined when the delegate is instantiated and then remains constant for the entire lifetime of the delegate. Diğer bir deyişle, oluşturulduktan sonra bir temsilcinin hedef çağrılabilir varlıklarını değiştirmek mümkün değildir.In other words, it is not possible to change the target callable entities of a delegate once it has been created. İki temsilci birleştirildiğinde veya bir diğeri (temsilci bildirimlerinden) kaldırıldığında, yeni bir temsilci oluşur; Mevcut temsilcinin içeriği değiştirilmedi.When two delegates are combined or one is removed from another (Delegate declarations), a new delegate results; no existing delegate has its contents changed.

Bir özellik, Dizin Oluşturucu, Kullanıcı tanımlı işleç, örnek Oluşturucu, yıkıcı veya statik oluşturucuya başvuran bir temsilci oluşturmak mümkün değildir.It is not possible to create a delegate that refers to a property, indexer, user-defined operator, instance constructor, destructor, or static constructor.

Yukarıda açıklandığı gibi, bir yöntem grubundan bir temsilci oluşturulduğunda, temsilci 'nin biçimsel parametre listesi ve dönüş türü, ne tür aşırı yüklenmiş yöntemlerin ekleneceğini belirleyin.As described above, when a delegate is created from a method group, the formal parameter list and return type of the delegate determine which of the overloaded methods to select. ÖrnekteIn the example

delegate double DoubleFunc(double x);

class A
{
    DoubleFunc f = new DoubleFunc(Square);

    static float Square(float x) {
        return x * x;
    }

    static double Square(double x) {
        return x * x;
    }
}

A.f Square Bu yöntem, biçimsel parametre listesi ve dönüş türü ile tam olarak eşleştiğinden, bu alan ikinci yönteme başvuran bir temsilci ile başlatılır DoubleFunc .the A.f field is initialized with a delegate that refers to the second Square method because that method exactly matches the formal parameter list and return type of DoubleFunc. İkinci Square Yöntem yoktu, derleme zamanı hatası oluşmuş olabilir.Had the second Square method not been present, a compile-time error would have occurred.

Anonim nesne oluşturma ifadeleriAnonymous object creation expressions

Anonim türdeki bir nesne oluşturmak için bir anonymous_object_creation_expression kullanılır.An anonymous_object_creation_expression is used to create an object of an anonymous type.

anonymous_object_creation_expression
    : 'new' anonymous_object_initializer
    ;

anonymous_object_initializer
    : '{' member_declarator_list? '}'
    | '{' member_declarator_list ',' '}'
    ;

member_declarator_list
    : member_declarator (',' member_declarator)*
    ;

member_declarator
    : simple_name
    | member_access
    | base_access
    | null_conditional_member_access
    | identifier '=' expression
    ;

Anonim bir nesne Başlatıcısı, anonim bir tür bildirir ve bu türün bir örneğini döndürür.An anonymous object initializer declares an anonymous type and returns an instance of that type. Anonim tür, doğrudan öğesinden devralan isimsiz bir sınıf türüdür object .An anonymous type is a nameless class type that inherits directly from object. Anonim bir türün üyeleri, türünün bir örneğini oluşturmak için kullanılan anonim nesne başlatıcıdan çıkarılan salt okunurdur salt yazılır özelliklerden oluşan bir dizidir.The members of an anonymous type are a sequence of read-only properties inferred from the anonymous object initializer used to create an instance of the type. Özellikle, formun anonim nesne BaşlatıcısıSpecifically, an anonymous object initializer of the form

new { p1 = e1, p2 = e2, ..., pn = en }

formun anonim türünü bildirirdeclares an anonymous type of the form

class __Anonymous1
{
    private readonly T1 f1;
    private readonly T2 f2;
    ...
    private readonly Tn fn;

    public __Anonymous1(T1 a1, T2 a2, ..., Tn an) {
        f1 = a1;
        f2 = a2;
        ...
        fn = an;
    }

    public T1 p1 { get { return f1; } }
    public T2 p2 { get { return f2; } }
    ...
    public Tn pn { get { return fn; } }

    public override bool Equals(object __o) { ... }
    public override int GetHashCode() { ... }
}

her birinin Tx karşılık gelen ifadenin türü ex .where each Tx is the type of the corresponding expression ex. Bir member_declarator kullanılan ifadenin türü olmalıdır.The expression used in a member_declarator must have a type. Bu nedenle, member_declarator bir ifadenin null veya anonim bir işlev olması için derleme zamanı hatası vardır.Thus, it is a compile-time error for an expression in a member_declarator to be null or an anonymous function. Ayrıca, ifadenin güvenli olmayan bir türü olması için derleme zamanı hatası da vardır.It is also a compile-time error for the expression to have an unsafe type.

Anonim bir türün ve parametresinin yönteminin adı, Equals derleyici tarafından otomatik olarak oluşturulur ve program metninde başvurulamaz.The names of an anonymous type and of the parameter to its Equals method are automatically generated by the compiler and cannot be referenced in program text.

Aynı programda aynı ada ve derleme zamanı türlerine sahip bir özellikler dizisini belirten iki anonim nesne başlatıcıları aynı şekilde aynı anonim türde örnekler oluşturacaktır.Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.

ÖrnekteIn the example

var p1 = new { Name = "Lawnmower", Price = 495.00 };
var p2 = new { Name = "Shovel", Price = 26.95 };
p1 = p2;

Son satırdaki atamaya izin verilir, çünkü p1 ve p2 aynı anonim türde.the assignment on the last line is permitted because p1 and p2 are of the same anonymous type.

Equals GetHashcode Anonim türler üzerindeki ve yöntemleri, öğesinden devralınan yöntemleri geçersiz kılar object ve Equals GetHashcode özelliklerin ve yalnızca tüm özellikleri eşitse, aynı anonim türdeki iki örnek eşitse eşit olmalıdır.The Equals and GetHashcode methods on anonymous types override the methods inherited from object, and are defined in terms of the Equals and GetHashcode of the properties, so that two instances of the same anonymous type are equal if and only if all their properties are equal.

Bir üye bildirimci basit bir ad (tür çıkarımı), bir üye erişimi (dinamik aşırı yükleme çözümlemesi için derleme zamanı denetimi), temel erişim (temel erişim) veya null koşullu üye erişimi (projeksiyon başlatıcıları olarak null Koşullu ifadeler) için kısaltılabilir.A member declarator can be abbreviated to a simple name (Type inference), a member access (Compile-time checking of dynamic overload resolution), a base access (Base access) or a null-conditional member access (Null-conditional expressions as projection initializers). Bu, projeksiyon başlatıcısı olarak adlandırılır ve aynı ada sahip bir özelliğe bir bildirim ve atama için toplu bir özelliktir.This is called a projection initializer and is shorthand for a declaration of and assignment to a property with the same name. Özellikle, formların üye bildirimcileriSpecifically, member declarators of the forms

identifier
expr.identifier

sırasıyla aşağıdaki gibi tam olarak eşdeğerdir:are precisely equivalent to the following, respectively:

identifier = identifier
identifier = expr.identifier

Bu nedenle, bir projeksiyon başlatıcısında tanımlayıcı hem değeri hem de değerin atandığı alanı veya özelliği seçer.Thus, in a projection initializer the identifier selects both the value and the field or property to which the value is assigned. Bir projeksiyon başlatıcısı projesi yalnızca bir değer değil, aynı zamanda değerin adı değildir.Intuitively, a projection initializer projects not just a value, but also the name of the value.

Typeof işleciThe typeof operator

typeofİşleci, System.Type bir türün nesnesini almak için kullanılır.The typeof operator is used to obtain the System.Type object for a type.

typeof_expression
    : 'typeof' '(' type ')'
    | 'typeof' '(' unbound_type_name ')'
    | 'typeof' '(' 'void' ')'
    ;

unbound_type_name
    : identifier generic_dimension_specifier?
    | identifier '::' identifier generic_dimension_specifier?
    | unbound_type_name '.' identifier generic_dimension_specifier?
    ;

generic_dimension_specifier
    : '<' comma* '>'
    ;

comma
    : ','
    ;

Typeof_expression ilk formu, bir typeof anahtar sözcükten sonra parantez içine alınmış bir tür ile oluşur.The first form of typeof_expression consists of a typeof keyword followed by a parenthesized type. Bu formun bir ifadesinin sonucu, System.Type belirtilen türün nesnesidir.The result of an expression of this form is the System.Type object for the indicated type. System.TypeVerilen herhangi bir tür için yalnızca bir nesne vardır.There is only one System.Type object for any given type. Bu, bir tür için  T typeof(T) == typeof(T) her zaman doğru olduğu anlamına gelir.This means that for a type T, typeof(T) == typeof(T) is always true. Tür olamaz dynamic .The type cannot be dynamic.

Typeof_expression ikinci biçimi bir typeof anahtar sözcükten ve sonra parantez içinde unbound_type_name oluşur.The second form of typeof_expression consists of a typeof keyword followed by a parenthesized unbound_type_name. Bir unbound_type_name bir type_name (ad alanı ve tür adları) çok benzerdir, çünkü bir unbound_type_name type_name bir type_argument_list içeren generic_dimension_specifier s 'yi içerir.An unbound_type_name is very similar to a type_name (Namespace and type names) except that an unbound_type_name contains generic_dimension_specifier s where a type_name contains type_argument_list s. Bir typeof_expression işleneni hem unbound_type_name hem de type_name her ikisi de bir generic_dimension_specifier veya type_argument_list içerdiğinde, belirteçlerin sırası bir type_name olarak kabul edilir.When the operand of a typeof_expression is a sequence of tokens that satisfies the grammars of both unbound_type_name and type_name, namely when it contains neither a generic_dimension_specifier nor a type_argument_list, the sequence of tokens is considered to be a type_name. Bir unbound_type_name anlamı aşağıdaki şekilde belirlenir:The meaning of an unbound_type_name is determined as follows:

  • Her bir generic_dimension_specifier , her bir type_argument aynı sayıda virgül ve anahtar sözcüğüne sahip bir type_argument_list değiştirerek belirteç dizisini bir type_name dönüştürün object . Convert the sequence of tokens to a type_name by replacing each generic_dimension_specifier with a type_argument_list having the same number of commas and the keyword object as each type_argument.
  • Tüm tür parametresi kısıtlamalarını yoksayarak elde edilen type_name değerlendirin.Evaluate the resulting type_name, while ignoring all type parameter constraints.
  • Unbound_type_name , ortaya çıkan oluşturulan türle ilişkili ilişkisiz genel tür (bağlı ve ilişkisiz türler) ile çözümlenir.The unbound_type_name resolves to the unbound generic type associated with the resulting constructed type (Bound and unbound types).

Typeof_expression sonucu, System.Type sonuçta elde edilen ilişkisiz genel türün nesnesidir.The result of the typeof_expression is the System.Type object for the resulting unbound generic type.

Üçüncü typeof_expression biçimi bir typeof anahtar sözcükten ve sonra parantez içine alınmış bir void anahtar sözcükten oluşur.The third form of typeof_expression consists of a typeof keyword followed by a parenthesized void keyword. Bu formun bir ifadesinin sonucu, System.Type bir türün yokluğunu temsil eden nesnedir.The result of an expression of this form is the System.Type object that represents the absence of a type. Tarafından döndürülen tür nesnesi typeof(void) herhangi bir tür için döndürülen tür nesnesinden farklıdır.The type object returned by typeof(void) is distinct from the type object returned for any type. Bu özel tür nesnesi, bir örneği ile void yöntemler de dahil olmak üzere herhangi bir yöntemin dönüş türünü temsil etmek için, bu yöntemlerin, dildeki yöntemlere izin veren sınıf kitaplıklarında yararlıdır System.Type .This special type object is useful in class libraries that allow reflection onto methods in the language, where those methods wish to have a way to represent the return type of any method, including void methods, with an instance of System.Type.

typeofİşleci bir tür parametresinde kullanılabilir.The typeof operator can be used on a type parameter. Sonuç, System.Type tür parametresine bağlanan çalışma zamanı türünün nesnesidir.The result is the System.Type object for the run-time type that was bound to the type parameter. typeofİşleci, oluşturulmuş bir tür veya ilişkisiz genel tür (bağlı ve ilişkisiz türler) üzerinde de kullanılabilir.The typeof operator can also be used on a constructed type or an unbound generic type (Bound and unbound types). System.Typeİlişkisiz genel bir tür için nesne, System.Type örnek türünün nesnesiyle aynı değildir.The System.Type object for an unbound generic type is not the same as the System.Type object of the instance type. Örnek türü her zaman çalışma zamanında kapalı oluşturulmuş bir tür olur, böylece nesne, System.Type kullanılan çalışma zamanı türü bağımsız değişkenlerine bağlıdır, ancak ilişkisiz genel türün tür bağımsız değişkenleri yoktur.The instance type is always a closed constructed type at run-time so its System.Type object depends on the run-time type arguments in use, while the unbound generic type has no type arguments.

ÖrnekteThe example

using System;

class X<T>
{
    public static void PrintTypes() {
        Type[] t = {
            typeof(int),
            typeof(System.Int32),
            typeof(string),
            typeof(double[]),
            typeof(void),
            typeof(T),
            typeof(X<T>),
            typeof(X<X<T>>),
            typeof(X<>)
        };
        for (int i = 0; i < t.Length; i++) {
            Console.WriteLine(t[i]);
        }
    }
}

class Test
{
    static void Main() {
        X<int>.PrintTypes();
    }
}

Aşağıdaki çıktıyı üretir:produces the following output:

System.Int32
System.Int32
System.String
System.Double[]
System.Void
System.Int32
X`1[System.Int32]
X`1[X`1[System.Int32]]
X`1[T]

intVe System.Int32 aynı türde olduğunu unutmayın.Note that int and System.Int32 are the same type.

Ayrıca, sonucu typeof(X<>) tür bağımsız değişkenine bağlı değildir, ancak sonucunu unutmayın typeof(X<T>) .Also note that the result of typeof(X<>) does not depend on the type argument but the result of typeof(X<T>) does.

Checked ve unchecked işleçleriThe checked and unchecked operators

checkedVe unchecked işleçleri, tam sayı türü aritmetik işlemler ve dönüştürmeler için taşma denetimi bağlamını denetlemek üzere kullanılır.The checked and unchecked operators are used to control the overflow checking context for integral-type arithmetic operations and conversions.

checked_expression
    : 'checked' '(' expression ')'
    ;

unchecked_expression
    : 'unchecked' '(' expression ')'
    ;

checkedİşleç içerilen ifadeyi işaretlenmiş bir bağlamda değerlendirir ve unchecked işleç içerilen ifadeyi işaretlenmemiş bir bağlamda değerlendirir.The checked operator evaluates the contained expression in a checked context, and the unchecked operator evaluates the contained expression in an unchecked context. Bir checked_expression veya unchecked_expression tam olarak bir parenthesized_expression (parantez içine alınmış ifadelerde) karşılık gelir, ancak içerilen ifade verilen taşma Denetim bağlamında değerlendirilir.A checked_expression or unchecked_expression corresponds exactly to a parenthesized_expression (Parenthesized expressions), except that the contained expression is evaluated in the given overflow checking context.

Taşma Denetim bağlamı da checked ve deyimleri aracılığıyla denetlenebilir unchecked (Checked ve unchecked deyimleri).The overflow checking context can also be controlled through the checked and unchecked statements (The checked and unchecked statements).

Aşağıdaki işlemler, checked ve işleçleri ve deyimleri tarafından oluşturulan taşma denetimi bağlamından etkilenir unchecked :The following operations are affected by the overflow checking context established by the checked and unchecked operators and statements:

Yukarıdaki işlemlerden biri hedef türünde temsil etmek için çok büyük bir sonuç üretdüğünde, işlemin gerçekleştirildiği bağlam, sonuçta elde edilen davranışı denetler:When one of the above operations produce a result that is too large to represent in the destination type, the context in which the operation is performed controls the resulting behavior:

  • Bir checked bağlamda, işlem sabit bir ifadesiyse (sabit ifadeler), bir derleme zamanı hatası oluşur.In a checked context, if the operation is a constant expression (Constant expressions), a compile-time error occurs. Aksi takdirde, işlem çalışma zamanında gerçekleştirildiğinde, bir oluşturulur System.OverflowException .Otherwise, when the operation is performed at run-time, a System.OverflowException is thrown.
  • Bir unchecked bağlamda, sonuç, hedef türüne sığmayan yüksek sıralı bitleri atarak kesilir.In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type.

Herhangi bir veya işleçten veya deyimlerde bulunmayan sabit olmayan ifadeler (çalışma zamanında değerlendirilen ifadeler) için checked unchecked , varsayılan taşma denetimi bağlamı unchecked dış faktörlerden (derleyici anahtarları ve yürütme ortamı yapılandırması gibi) değerlendirme için çağrı değildir checked .For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation.

Sabit ifadeler (derleme zamanında tam olarak değerlendirilebilecek ifadeler) için varsayılan taşma denetimi bağlamı her zaman olur checked .For constant expressions (expressions that can be fully evaluated at compile-time), the default overflow checking context is always checked. Bir sabit ifade açıkça bir bağlamda yerleştirilmediği unchecked için, ifadenin derleme zamanı değerlendirmesi sırasında oluşan taşmalar her zaman derleme zamanı hatalarına neden olur.Unless a constant expression is explicitly placed in an unchecked context, overflows that occur during the compile-time evaluation of the expression always cause compile-time errors.

Anonim işlevin gövdesi, checked unchecked anonim işlevin gerçekleştiği bağlamdan etkilenmez.The body of an anonymous function is not affected by checked or unchecked contexts in which the anonymous function occurs.

ÖrnekteIn the example

class Test
{
    static readonly int x = 1000000;
    static readonly int y = 1000000;

    static int F() {
        return checked(x * y);      // Throws OverflowException
    }

    static int G() {
        return unchecked(x * y);    // Returns -727379968
    }

    static int H() {
        return x * y;               // Depends on default
    }
}

hiçbir deyimin hiçbiri derleme zamanında değerlendirilemediğinden, derleme zamanı hataları bildirilmemiştir.no compile-time errors are reported since neither of the expressions can be evaluated at compile-time. Çalışma zamanında F yöntemi bir oluşturur System.OverflowException ve G yöntemi-727379968 döndürür (Aralık dışı sonucun alt 32 bitleri).At run-time, the F method throws a System.OverflowException, and the G method returns -727379968 (the lower 32 bits of the out-of-range result). Yönteminin davranışı, H derleme için varsayılan taşma denetimi bağlamına bağlıdır, ancak aynı veya ile aynı olur F G .The behavior of the H method depends on the default overflow checking context for the compilation, but it is either the same as F or the same as G.

ÖrnekteIn the example

class Test
{
    const int x = 1000000;
    const int y = 1000000;

    static int F() {
        return checked(x * y);      // Compile error, overflow
    }

    static int G() {
        return unchecked(x * y);    // Returns -727379968
    }

    static int H() {
        return x * y;               // Compile error, overflow
    }
}

içindeki sabit ifadeler değerlendirilirken meydana gelen taşmalar F ve H ifadeler bir bağlamda değerlendirildiğinden derleme zamanı hatalarının raporlanmasına neden olur checked .the overflows that occur when evaluating the constant expressions in F and H cause compile-time errors to be reported because the expressions are evaluated in a checked context. İçinde sabit ifade değerlendirilirken bir taşma da oluşur G , ancak değerlendirme bir bağlamda gerçekleşirken unchecked taşma bildirilmedi.An overflow also occurs when evaluating the constant expression in G, but since the evaluation takes place in an unchecked context, the overflow is not reported.

checkedVe unchecked işleçleri yalnızca, " ( " ve "" belirteçlerinde bulunan metin içeriğini eklemek bu işlemler için taşma denetimi bağlamını etkiler ) .The checked and unchecked operators only affect the overflow checking context for those operations that are textually contained within the "(" and ")" tokens. İşleçler, içerilen ifadenin hesaplanmasının sonucu olarak çağrılan işlev üyelerini etkilemez.The operators have no effect on function members that are invoked as a result of evaluating the contained expression. ÖrnekteIn the example

class Test
{
    static int Multiply(int x, int y) {
        return x * y;
    }

    static int F() {
        return checked(Multiply(1000000, 1000000));
    }
}

' nin kullanımı checked , F içindeki değerlendirmesini etkilemez x * y Multiply , bu nedenle x * y varsayılan taşma denetimi bağlamında değerlendirilir.the use of checked in F does not affect the evaluation of x * y in Multiply, so x * y is evaluated in the default overflow checking context.

uncheckedİşleci, işaretli integral türlerinin sabitlerini onaltılık gösterimde yazarken kullanışlıdır.The unchecked operator is convenient when writing constants of the signed integral types in hexadecimal notation. Örnek:For example:

class Test
{
    public const int AllBits = unchecked((int)0xFFFFFFFF);

    public const int HighBit = unchecked((int)0x80000000);
}

Yukarıdaki onaltılık sabitlerin her ikisi de türündedir uint .Both of the hexadecimal constants above are of type uint. Sabitler, işleç olmadan, Aralık dışında olduğundan, int unchecked ' a yapılan yayınlar int derleme zamanı hataları oluşturur.Because the constants are outside the int range, without the unchecked operator, the casts to int would produce compile-time errors.

checkedVe unchecked işleçleri ve deyimleri, programcıların bazı sayısal hesaplamaların belirli yönlerini denetlemesine olanak tanır.The checked and unchecked operators and statements allow programmers to control certain aspects of some numeric calculations. Ancak, bazı sayısal işleçlerin davranışı işlenenlerinin veri türlerine bağlıdır.However, the behavior of some numeric operators depends on their operands' data types. Örneğin, iki ondalıkın çarpılması her zaman açıkça bir yapı içinde bile taşma üzerinde bir özel durumla sonuçlanır unchecked .For example, multiplying two decimals always results in an exception on overflow even within an explicitly unchecked construct. Benzer şekilde, iki float çarpılması hiçbir şekilde açıkça bir yapı içinde bile taşma durumunda hiçbir durum ile sonuçlanır checked .Similarly, multiplying two floats never results in an exception on overflow even within an explicitly checked construct. Ayrıca, diğer işleçler, varsayılan veya açık olsun denetim modundan hiçbir şekilde etkilenmez.In addition, other operators are never affected by the mode of checking, whether default or explicit.

Varsayılan değer ifadeleriDefault value expressions

Varsayılan değer ifadesi bir türün varsayılan değerini (varsayılan değerler) almak için kullanılır.A default value expression is used to obtain the default value (Default values) of a type. Tür parametresi bir değer türü veya bir başvuru türü ise, genellikle varsayılan değer ifadesi tür parametreleri için kullanılır.Typically a default value expression is used for type parameters, since it may not be known if the type parameter is a value type or a reference type. ( null Tür parametresi bir başvuru türü olarak bilinmediği takdirde, sabit değerinden bir tür parametresine dönüştürme yok.)(No conversion exists from the null literal to a type parameter unless the type parameter is known to be a reference type.)

default_value_expression
    : 'default' '(' type ')'
    ;

Bir default_value_expression tür , çalışma zamanında bir başvuru türü olarak değerlendirilirse, sonuç null o türe dönüştürülür.If the type in a default_value_expression evaluates at run-time to a reference type, the result is null converted to that type. Bir default_value_expression türü çalışma zamanında bir değer türüne değerlendirilirse, sonuç, value_type varsayılan değeridir (Varsayılan oluşturucular).If the type in a default_value_expression evaluates at run-time to a value type, the result is the value_type's default value (Default constructors).

Default_value_expression bir başvuru türü veya bir başvuru türü olarak bilinen bir tür parametresi ise, bir sabit ifadedir (sabit ifadeler).A default_value_expression is a constant expression (Constant expressions) if the type is a reference type or a type parameter that is known to be a reference type (Type parameter constraints). Ayrıca default_value_expression , tür,,,,,,, sbyte byte short ushort int uint long , ulong , char ,,,,,,,,,, float , double , decimal , bool ,,,,,,,,, veya herhangi bir numaralandırma türü olan bir sabit ifadedir.In addition, a default_value_expression is a constant expression if the type is one of the following value types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, or any enumeration type.

NameOf ifadeleriNameof expressions

Bir nameof_expression , bir program varlığının adını sabit bir dize olarak almak için kullanılır.A nameof_expression is used to obtain the name of a program entity as a constant string.

nameof_expression
    : 'nameof' '(' named_entity ')'
    ;

named_entity
    : simple_name
    | named_entity_target '.' identifier type_argument_list?
    ;

named_entity_target
    : 'this'
    | 'base'
    | named_entity 
    | predefined_type 
    | qualified_alias_member
    ;

Dilbilgisi, named_entity işleneni her zaman bir ifadedir.Grammatically speaking, the named_entity operand is always an expression. nameofAyrılmış bir anahtar sözcük olmadığından, bir NameOf ifadesi her zaman bir basit ad çağrısı ile sözdizimsel olarak belirsizdir nameof .Because nameof is not a reserved keyword, a nameof expression is always syntactically ambiguous with an invocation of the simple name nameof. Uyumluluk nedenleriyle, adın bir ad araması (basit adlar) nameof başarılı olursa, çağrının yasal olup olmamasına bakılmaksızın ifade invocation_expression olarak değerlendirilir.For compatibility reasons, if a name lookup (Simple names) of the name nameof succeeds, the expression is treated as an invocation_expression -- regardless of whether the invocation is legal. Aksi takdirde, bir nameof_expression.Otherwise it is a nameof_expression.

Bir nameof_expression named_entity anlamı, ifadenin anlamı olarak ifade edilir; Yani simple_name, bir base_access veya member_access olarak.The meaning of the named_entity of a nameof_expression is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. Ancak, basit adlarda ve üye erişimlerinde açıklanan aramanın bir hata ile sonuçlandığı durumlarda, bir örnek üyesi statik bir bağlamda bulunduğu için, nameof_expression böyle bir hata üretir.However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.

Bir yöntem grubunu bir type_argument_list sahip olacak şekilde belirlemek named_entity bir derleme zamanı hatasıdır.It is a compile-time error for a named_entity designating a method group to have a type_argument_list. Named_entity_target türüne sahip olan bir derleme zamanı hatasıdır dynamic .It is a compile time error for a named_entity_target to have the type dynamic.

Nameof_expression , türünde sabit bir ifadedir string ve çalışma zamanında hiçbir etkiye sahip değildir.A nameof_expression is a constant expression of type string, and has no effect at runtime. Özellikle, named_entity değerlendirilmez ve kesin atama analizinin amaçları doğrultusunda yok sayılır (basit ifadeler için genel kurallar).Specifically, its named_entity is not evaluated, and is ignored for the purposes of definite assignment analysis (General rules for simple expressions). Değeri, isteğe bağlı son type_argument_list önce named_entity , aşağıdaki şekilde dönüştürülecek olan en son tanıtıcıdır:Its value is the last identifier of the named_entity before the optional final type_argument_list, transformed in the following way:

  • " @ " 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.
  • Formatting_characters kaldırılır.Any formatting_characters are removed.

Bunlar, tanımlayıcılar arasında eşitlik test edilirken tanımlayıcılarla uygulanan dönüşümlerdir.These are the same transformations applied in Identifiers when testing equality between identifiers.

TODO: örneklerTODO: examples

Anonim yöntem ifadeleriAnonymous method expressions

Bir anonymous_method_expression anonim bir işlevi tanımlamanın iki yöntemlerinden biridir.An anonymous_method_expression is one of two ways of defining an anonymous function. Bunlar, anonim işlev ifadelerindedaha ayrıntılı olarak açıklanmıştır.These are further described in Anonymous function expressions.

Birli işleçlerUnary operators

?,, + , - ! , ~ ,,, ++ -- Cast ve await işleçlere Birli İşleçler denir.The ?, +, -, !, ~, ++, --, cast, and await operators are called the unary operators.

unary_expression
    : primary_expression
    | null_conditional_expression
    | '+' unary_expression
    | '-' unary_expression
    | '!' unary_expression
    | '~' unary_expression
    | pre_increment_expression
    | pre_decrement_expression
    | cast_expression
    | await_expression
    | unary_expression_unsafe
    ;

Bir unary_expression işleneni derleme zamanı türüne sahipse dynamic , dinamik olarak bağlanır (dinamik bağlama).If the operand of a unary_expression has the compile-time type dynamic, it is dynamically bound (Dynamic binding). Bu durumda unary_expression derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, işlenenin çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir.In this case the compile-time type of the unary_expression is dynamic, and the resolution described below will take place at run-time using the run-time type of the operand.

Null-koşullu işleçNull-conditional operator

Null koşullu işleç, yalnızca bu işlenen null değilse, işlenene bir işlem listesi uygular.The null-conditional operator applies a list of operations to its operand only if that operand is non-null. Aksi halde işleci uygulamanın sonucu null .Otherwise the result of applying the operator is null.

null_conditional_expression
    : primary_expression null_conditional_operations
    ;

null_conditional_operations
    : null_conditional_operations? '?' '.' identifier type_argument_list?
    | null_conditional_operations? '?' '[' argument_list ']'
    | null_conditional_operations '.' identifier type_argument_list?
    | null_conditional_operations '[' argument_list ']'
    | null_conditional_operations '(' argument_list? ')'
    ;

İşlem listesi, üye erişimi ve öğe erişim işlemleri (kendileri de null koşullu olabilir) ve çağırma içerebilir.The list of operations can include member access and element access operations (which may themselves be null-conditional), as well as invocation.

Örneğin, ifadesi a.b?[0]?.c() bir primary_expression a.b ve null_conditional_operations ?[0] (null-koşullu öğe erişimi), ( ?.c null-koşullu üye erişimi) ve () (çağırma) içeren bir null_conditional_expression.For example, the expression a.b?[0]?.c() is a null_conditional_expression with a primary_expression a.b and null_conditional_operations ?[0] (null-conditional element access), ?.c (null-conditional member access) and () (invocation).

Primary_expression sahip bir null_conditional_expression E için P , E0 metin içeriğini eklemek tarafından alınan ve ? sahip olduğu null_conditional_operations her birinden önde gelen ifade olmasına izin verir E .For a null_conditional_expression E with a primary_expression P, let E0 be the expression obtained by textually removing the leading ? from each of the null_conditional_operations of E that have one. Kavramsal olarak, E0 s tarafından temsil edilen null denetimlerin hiçbiri bir bulamazsa, değerlendirilecek ifadedir ? null .Conceptually, E0 is the expression that will be evaluated if none of the null checks represented by the ?s do find a null.

Ayrıca, E1 metin içeriğini eklemek tarafından elde edilen ifadenin önünde ? null_conditional_operations E .Also, let E1 be the expression obtained by textually removing the leading ? from just the first of the null_conditional_operations in E. Bu, bir birincil ifadeye (yalnızca bir tane varsa ? ) veya başka bir null_conditional_expression yol açabilir.This may lead to a primary-expression (if there was just one ?) or to another null_conditional_expression.

Örneğin, E ifadesiyse, ifade a.b?[0]?.c() ve ifadedir E0 a.b[0].c() E1 a.b[0]?.c() .For example, if E is the expression a.b?[0]?.c(), then E0 is the expression a.b[0].c() and E1 is the expression a.b[0]?.c().

E0Hiçbir şey olarak sınıflandırıldıysanız, E hiçbir şey Nothing olarak sınıflandırılır.If E0 is classified as nothing, then E is classified as nothing. Aksi halde E bir değer olarak sınıflandırılır.Otherwise E is classified as a value.

E0 ve E1 öğesinin anlamını belirlemede kullanılır E :E0 and E1 are used to determine the meaning of E:

  • E Statement_expression olarak gerçekleşirse, öğesinin anlamı E ifadesiyle aynıdırIf E occurs as a statement_expression the meaning of E is the same as the statement

    if ((object)P != null) E1;
    

    Bu P yalnızca bir kez değerlendirilir.except that P is evaluated only once.

  • Aksi takdirde, E0 hiçbir şey bir derleme zamanı hatası olarak sınıflandırılursa.Otherwise, if E0 is classified as nothing a compile-time error occurs.

  • Aksi takdirde, T0 türü olmasına izin verin E0 .Otherwise, let T0 be the type of E0.

    • T0Bir başvuru türü veya null yapılamayan bir değer türü olarak bilinen bir tür parametresi ise, derleme zamanı hatası oluşur.If T0 is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.

    • T0Null yapılamayan bir değer türü ise, türü E T0? ve öğesinin anlamı EIf T0 is a non-nullable value type, then the type of E is T0?, and the meaning of E is the same as

      ((object)P == null) ? (T0?)null : E1
      

      Ancak P yalnızca bir kez değerlendirilir.except that P is evaluated only once.

    • Aksi takdirde, E türü T0 ve E 'nin anlamıOtherwise the type of E is T0, and the meaning of E is the same as

      ((object)P == null) ? null : E1
      

      Ancak P yalnızca bir kez değerlendirilir.except that P is evaluated only once.

E1Kendisi bir null_conditional_expression ise, bu kurallar tekrar uygulanır, null daha fazla olmaz ? ve ifade, birincil ifadeye kadar olan tüm şekilde azaltılır E0 .If E1 is itself a null_conditional_expression, then these rules are applied again, nesting the tests for null until there are no further ?'s, and the expression has been reduced all the way down to the primary-expression E0.

Örneğin, ifadesi a.b?[0]?.c() deyiminde olduğu gibi bir deyim ifadesi olarak gerçekleşirse:For example, if the expression a.b?[0]?.c() occurs as a statement-expression, as in the statement:

a.b?[0]?.c();

anlamı şu şekilde eşdeğerdir:its meaning is equivalent to:

if (a.b != null) a.b[0]?.c();

yeniden eşittir:which again is equivalent to:

if (a.b != null) if (a.b[0] != null) a.b[0].c();

Ancak a.b a.b[0] yalnızca bir kez değerlendirilir.Except that a.b and a.b[0] are evaluated only once.

Değeri kullanıldığı bir bağlamda gerçekleşirse, şöyle olduğu gibi:If it occurs in a context where its value is used, as in:

var x = a.b?[0]?.c();

son çağrının türünün null yapılamayan bir değer türü olmadığı varsayılarak, anlamı şu değere eşittir:and assuming that the type of the final invocation is not a non-nullable value type, its meaning is equivalent to:

var x = (a.b == null) ? null : (a.b[0] == null) ? null : a.b[0].c();

Ancak a.b a.b[0] yalnızca bir kez değerlendirilir.except that a.b and a.b[0] are evaluated only once.

Projeksiyon başlatıcıları olarak null Koşullu ifadelerNull-conditional expressions as projection initializers

Null koşullu bir ifadeye, yalnızca bir (isteğe bağlı null koşullu) üye erişimiyle biterse bir anonymous_object_creation_expression (anonim nesne oluşturma ifadelerinde) member_declarator olarak izin verilir.A null-conditional expression is only allowed as a member_declarator in an anonymous_object_creation_expression (Anonymous object creation expressions) if it ends with an (optionally null-conditional) member access. Dilbilgisi, bu gereksinim şöyle ifade edilebilir:Grammatically, this requirement can be expressed as:

null_conditional_member_access
    : primary_expression null_conditional_operations? '?' '.' identifier type_argument_list?
    | primary_expression null_conditional_operations '.' identifier type_argument_list?
    ;

Bu, yukarıdaki null_conditional_expression dilbilgisinde özel bir durumdur.This is a special case of the grammar for null_conditional_expression above. Anonim nesne oluşturma ifadelerinde member_declarator için üretim, yalnızca null_conditional_member_access içerir.The production for member_declarator in Anonymous object creation expressions then includes only null_conditional_member_access.

Deyim ifadeleri olarak null Koşullu ifadelerNull-conditional expressions as statement expressions

Null koşullu ifadeye yalnızca bir çağrı ile bitiyorsa statement_expression (ifade deyimleri) olarak izin verilir.A null-conditional expression is only allowed as a statement_expression (Expression statements) if it ends with an invocation. Dilbilgisi, bu gereksinim şöyle ifade edilebilir:Grammatically, this requirement can be expressed as:

null_conditional_invocation_expression
    : primary_expression null_conditional_operations '(' argument_list? ')'
    ;

Bu, yukarıdaki null_conditional_expression dilbilgisinde özel bir durumdur.This is a special case of the grammar for null_conditional_expression above. Expression deyimlerdeki statement_expression için üretim, yalnızca null_conditional_invocation_expression içerir.The production for statement_expression in Expression statements then includes only null_conditional_invocation_expression.

Birli artı işleciUnary plus operator

Formun bir işlemi için +x , belirli bir operatör uygulamasını seçmek üzere birli işleç aşırı yükleme çözümlemesi (birli operatör aşırı yükleme çözünürlüğü) uygulanır.For an operation of the form +x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. İşlenen, seçili işlecin parametre türüne dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Önceden tanımlanmış birli artı işleçleri şunlardır:The predefined unary plus operators are:

int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);

Bu işleçlerin her biri için sonuç yalnızca işlenenin değeridir.For each of these operators, the result is simply the value of the operand.

Birli eksi işaretiUnary minus operator

Formun bir işlemi için -x , belirli bir operatör uygulamasını seçmek üzere birli işleç aşırı yükleme çözümlemesi (birli operatör aşırı yükleme çözünürlüğü) uygulanır.For an operation of the form -x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. İşlenen, seçili işlecin parametre türüne dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Önceden tanımlanmış olumsuzlama işleçleri şunlardır:The predefined negation operators are:

  • Tamsayı değilleme:Integer negation:

    int operator -(int x);
    long operator -(long x);
    

    Sonuç, sıfırdan çıkartılacak şekilde hesaplanır x .The result is computed by subtracting x from zero. Değeri, x işlenen türünün en küçük gösterilebilir tablo değeri (-2 ^ 31 for int veya-2 ^ 63 long ) ise, ' nin matematik Olumsuzlaştırma x türü, işlenen türü içinde gösterilemeyen bir tablo değildir.If the value of x is the smallest representable value of the operand type (-2^31 for int or -2^63 for long), then the mathematical negation of x is not representable within the operand type. Bu bir bağlam içinde oluşursa checked , bir oluşturulur System.OverflowException ; bir bağlam içinde oluşursa unchecked , sonuç işlenenin değeridir ve taşma raporlanır.If this occurs within a checked context, a System.OverflowException is thrown; if it occurs within an unchecked context, the result is the value of the operand and the overflow is not reported.

    Olumsuzlama işlecinin işleneni tür ise uint , türüne dönüştürülür long ve sonuç türü olur long .If the operand of the negation operator is of type uint, it is converted to type long, and the type of the result is long. Özel durum int -2147483648 (-2 ^ 31) değerinin ondalık tamsayı sabit değeri (tamsayı sabit değerler) olarak yazılmasına izin veren kuraldır.An exception is the rule that permits the int value -2147483648 (-2^31) to be written as a decimal integer literal (Integer literals).

    Olumsuzlama işlecinin işleneni tür ise ulong , derleme zamanı hatası oluşur.If the operand of the negation operator is of type ulong, a compile-time error occurs. Bir özel durum, long -9223372036854775808 (-2 ^ 63) değerinin ondalık tamsayı sabit değeri (tamsayı değişmezdeğer) olarak yazılmasına izin veren kuraldır.An exception is the rule that permits the long value -9223372036854775808 (-2^63) to be written as a decimal integer literal (Integer literals).

  • Kayan nokta olumsuzlama:Floating-point negation:

    float operator -(float x);
    double operator -(double x);
    

    Sonucu, x işareti ters çevrilme ile değeridir.The result is the value of x with its sign inverted. xNaN ise, sonuç de NaN olur.If x is NaN, the result is also NaN.

  • Ondalık olumsuzlama:Decimal negation:

    decimal operator -(decimal x);
    

    Sonuç, sıfırdan çıkartılacak şekilde hesaplanır x .The result is computed by subtracting x from zero. Decimal olumsuzlama, türünün birli eksi işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Decimal negation is equivalent to using the unary minus operator of type System.Decimal.

Mantıksal değilleme işleciLogical negation operator

Formun bir işlemi için !x , belirli bir operatör uygulamasını seçmek üzere birli işleç aşırı yükleme çözümlemesi (birli operatör aşırı yükleme çözünürlüğü) uygulanır.For an operation of the form !x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. İşlenen, seçili işlecin parametre türüne dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Yalnızca bir tane önceden tanımlanmış mantıksal olumsuzlama işleci var:Only one predefined logical negation operator exists:

bool operator !(bool x);

Bu işleç, işlenenin mantıksal olumsuzunu hesaplar: işlenen ise true sonuç olur false .This operator computes the logical negation of the operand: If the operand is true, the result is false. İşlenen false ise sonuç trueolur.If the operand is false, the result is true.

Bit düzeyinde tamamlama işleciBitwise complement operator

Formun bir işlemi için ~x , belirli bir operatör uygulamasını seçmek üzere birli işleç aşırı yükleme çözümlemesi (birli operatör aşırı yükleme çözünürlüğü) uygulanır.For an operation of the form ~x, unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. İşlenen, seçili işlecin parametre türüne dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operand is converted to the parameter type of the selected operator, and the type of the result is the return type of the operator. Önceden tanımlanmış bit düzeyinde tamamlama işleçleri şunlardır:The predefined bitwise complement operators are:

int operator ~(int x);
uint operator ~(uint x);
long operator ~(long x);
ulong operator ~(ulong x);

Bu işleçlerin her biri için, işlemin sonucu, ' nin bit düzeyinde tamamlayıcısı olur x .For each of these operators, the result of the operation is the bitwise complement of x.

Her numaralandırma türü E örtük olarak aşağıdaki bit düzeyinde tamamlayıcı işleci sağlar:Every enumeration type E implicitly provides the following bitwise complement operator:

E operator ~(E x);

Değerlendirme sonucu olarak ~x , x temel alınan bir tür numaralandırma türünün bir ifadesi olduğu, ' ın E U (E)(~(U)x) E her zaman bir unchecked bağlamda (denetlenen ve işaretlenmemiş operatörler) olduğu gibi gerçekleştirilmesi dışında, ' ın değerlendirmesiyle tamamen aynı olmasıdır.The result of evaluating ~x, where x is an expression of an enumeration type E with an underlying type U, is exactly the same as evaluating (E)(~(U)x), except that the conversion to E is always performed as if in an unchecked context (The checked and unchecked operators).

Önek arttırma ve azaltma işleçleriPrefix increment and decrement operators

pre_increment_expression
    : '++' unary_expression
    ;

pre_decrement_expression
    : '--' unary_expression
    ;

Önek artırma veya azaltma işleminin işleneni, değişken olarak sınıflandırılmış bir ifade, özellik erişimi veya Dizin Oluşturucu erişimi olmalıdır.The operand of a prefix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. İşlemin sonucu, işlenenden aynı türde bir değerdir.The result of the operation is a value of the same type as the operand.

Bir önek artış veya azaltma işleminin işleneni bir özellik veya Dizin Oluşturucu erişimi ise, özelliğin veya dizin oluşturucunun hem a hem de erişimcisi olmalıdır get set .If the operand of a prefix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. Bu durumda, bir bağlama zamanı hatası oluşur.If this is not the case, a binding-time error occurs.

Tekil operatör aşırı yükleme çözümü (birli operatör aşırı yükleme çözünürlüğü) belirli bir operatör uygulamasını seçmek için uygulanır.Unary operator overload resolution (Unary operator overload resolution) is applied to select a specific operator implementation. ++ -- Şu türler için önceden tanımlanmış ve işleçler var: sbyte ,,,, byte short ushort int , uint , long , ulong , char , float , double , decimal ve herhangi bir numaralandırma türü.Predefined ++ and -- operators exist for the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, and any enum type. Önceden tanımlanmış ++ işleçler, işlenene 1 eklenerek üretilen değeri döndürür ve önceden tanımlanmış -- işleçler, işleneni 1 çıkararak üretilen değeri döndürür.The predefined ++ operators return the value produced by adding 1 to the operand, and the predefined -- operators return the value produced by subtracting 1 from the operand. Bir checked bağlamda, bu ekleme veya çıkarma sonucunda elde edilen sonuç, sonuç türü aralığının dışındaysa ve sonuç türü bir integral türü ya da numaralandırma türüdür, bir oluşturulur System.OverflowException .In a checked context, if the result of this addition or subtraction is outside the range of the result type and the result type is an integral type or enum type, a System.OverflowException is thrown.

Bir önek için çalışma zamanı işleme, formun artış veya azaltma işlemini veya ++x --x aşağıdaki adımlardan oluşur:The run-time processing of a prefix increment or decrement operation of the form ++x or --x consists of the following steps:

  • xBir değişken olarak sınıflandırıldıysanız:If x is classified as a variable:
    • x değişkeni üretmek için değerlendirilir.x is evaluated to produce the variable.
    • Seçilen işleç, x bağımsız değişkeni olarak değeriyle çağrılır.The selected operator is invoked with the value of x as its argument.
    • İşleci tarafından döndürülen değer, değerlendirmesi tarafından verilen konumda depolanır x .The value returned by the operator is stored in the location given by the evaluation of x.
    • İşleci tarafından döndürülen değer işlemin sonucu olur.The value returned by the operator becomes the result of the operation.
  • xÖzellik veya Dizin Oluşturucu erişimi olarak sınıflandırıldıysanız:If x is classified as a property or indexer access:
    • İle ilişkili örnek ifadesi (değilse x static ) ve bağımsız değişken listesi ( x bir Dizin Oluşturucu erişimsiyse) x değerlendirilir ve sonuçlar sonraki get ve set erişimci etkinleştirmeleri içinde kullanılır.The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
    • getErişimcisi x çağrılır.The get accessor of x is invoked.
    • Seçili operatör, get bağımsız değişkeni olarak erişimci tarafından döndürülen değerle çağrılır.The selected operator is invoked with the value returned by the get accessor as its argument.
    • setErişimcisi, x bağımsız değişkeni olarak işleç tarafından döndürülen değerle çağrılır value .The set accessor of x is invoked with the value returned by the operator as its value argument.
    • İşleci tarafından döndürülen değer işlemin sonucu olur.The value returned by the operator becomes the result of the operation.

++Ve -- işleçleri de sonek gösterimini (Sonek artışı ve azaltma işleçleri) destekler.The ++ and -- operators also support postfix notation (Postfix increment and decrement operators). Genellikle, x++ veya sonucu x-- x işlemin önünde değeri olur, ancak sonucu işlemden ++x --x x sonraki değeridir.Typically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. Her iki durumda da, x işlemden sonra aynı değere sahiptir.In either case, x itself has the same value after the operation.

operator++Ya operator-- da bir uygulama, sonek veya ön ek gösterimi kullanılarak çağrılabilir.An operator++ or operator-- implementation can be invoked using either postfix or prefix notation. İki gösterimler için ayrı işleç uygulamalarına sahip olmak mümkün değildir.It is not possible to have separate operator implementations for the two notations.

Atama ifadeleriCast expressions

Bir ifadeyi açıkça verilen bir türe dönüştürmek için cast_expression kullanılır.A cast_expression is used to explicitly convert an expression to a given type.

cast_expression
    : '(' type ')' unary_expression
    ;

Bir (T)E T tür olan ve bir unary_expression olan cast_expression formun bir türü, bir E Açık dönüştürme (Açık dönüştürmeler) gerçekleştirir E T .A cast_expression of the form (T)E, where T is a type and E is a unary_expression, performs an explicit conversion (Explicit conversions) of the value of E to type T. ' Den hiçbir açık dönüştürme yoksa E T , bir bağlama zamanı hatası oluşur.If no explicit conversion exists from E to T, a binding-time error occurs. Aksi takdirde, sonuç açık dönüştürme tarafından üretilen değerdir.Otherwise, the result is the value produced by the explicit conversion. Sonuç, bir değişken olduğunu belirtse bile her zaman bir değer olarak sınıflandırılır E .The result is always classified as a value, even if E denotes a variable.

Bir cast_expression için dilbilgisi, belirli sözdizimsel belirsizlikleri sağlar.The grammar for a cast_expression leads to certain syntactic ambiguities. Örneğin, ifadesi (x)-y bir cast_expression ( -y türüne atama x ) veya parenthesized_expression ile birleştirilmiş bir additive_expression olarak (değeri hesaplayan) olarak yorumlanabilecek x - y) .For example, the expression (x)-y could either be interpreted as a cast_expression (a cast of -y to type x) or as an additive_expression combined with a parenthesized_expression (which computes the value x - y).

Cast_expression belirsizlikleri çözümlemek için aşağıdaki kural bulunur: parantez içine alınmış bir veya daha fazla belirteçdizisi (boşluk), yalnızca aşağıdakilerden en az biri doğru ise, bir cast_expression başlangıcını kabul ediyor:To resolve cast_expression ambiguities, the following rule exists: A sequence of one or more token s (White space) enclosed in parentheses is considered the start of a cast_expression only if at least one of the following are true:

  • Belirteçlerin sırası, bir tür için doğru dilbilgisinde bulunur, ancak bir ifade için kullanılamaz.The sequence of tokens is correct grammar for a type, but not for an expression.
  • Belirteçlerin sırası, bir tür için doğru dilbilgisidir ve kapatma parantezinden hemen sonraki belirteç " ~ ", belirteç " ! ", belirteç " ( ", bir tanımlayıcı (Unicode karakter kaçış dizileri), bir sabit değer (değişmezdeğer) veya ve dışında herhangi bir anahtar sözcüğü (anahtarsözcük) olur as is .The sequence of tokens is correct grammar for a type, and the token immediately following the closing parentheses is the token "~", the token "!", the token "(", an identifier (Unicode character escape sequences), a literal (Literals), or any keyword (Keywords) except as and is.

Yukarıdaki "doğru dilbilgisi" terimi, yalnızca belirteçlerin sırasının belirli dilbilgisi üretimine uyması gerektiği anlamına gelir.The term "correct grammar" above means only that the sequence of tokens must conform to the particular grammatical production. Bu, özellikle herhangi bir anayayrılan tanımlayıcıların gerçek anlamını düşünmez.It specifically does not consider the actual meaning of any constituent identifiers. Örneğin, x ve tanımlayıcıları ise y , x.y gerçekten bir tür belirtmese bile, bir tür için doğru dilbilgisi olur x.y .For example, if x and y are identifiers, then x.y is correct grammar for a type, even if x.y doesn't actually denote a type.

Kesinleştirme kuralından x sonra, ve y tanımlayıcıları,,, (x)y (x)(y) ve (x)(-y) cast_expression s ise, ancak (x)-y x bir tür tanımlarsa bile, değildir.From the disambiguation rule it follows that, if x and y are identifiers, (x)y, (x)(y), and (x)(-y) are cast_expression s, but (x)-y is not, even if x identifies a type. Ancak, x önceden tanımlanmış bir türü (gibi) tanımlayan bir anahtar sözcüktür int , tüm dört form cast_expression s 'dir (böyle bir anahtar sözcük muhtemelen kendisi tarafından bir ifade olmadığı için).However, if x is a keyword that identifies a predefined type (such as int), then all four forms are cast_expression s (because such a keyword could not possibly be an expression by itself).

Await ifadeleriAwait expressions

Await işleci, işlenen tarafından temsil edilen zaman uyumsuz işlem tamamlanana kadar kapsayan zaman uyumsuz işlevin değerlendirmesini askıya almak için kullanılır.The await operator is used to suspend evaluation of the enclosing async function until the asynchronous operation represented by the operand has completed.

await_expression
    : 'await' unary_expression
    ;

Bir await_expression yalnızca zaman uyumsuz bir işlevin gövdesinde kullanılabilir (zaman uyumsuz işlevler).An await_expression is only allowed in the body of an async function (Async functions). En yakın kapsayan zaman uyumsuz işlevi içinde, bu yerlerde bir await_expression gerçekleşmeyebilir:Within the nearest enclosing async function, an await_expression may not occur in these places:

  • İç içe geçmiş (zaman uyumsuz) anonim bir işlev içindeInside a nested (non-async) anonymous function
  • Lock_statement bloğunun içindeInside the block of a lock_statement
  • Güvenli olmayan bir bağlamdaIn an unsafe context

Bir await_expression , bir query_expression içinde çoğu yerde gerçekleşmediğini unutmayın, çünkü bunlar sözdizimsel olarak zaman uyumsuz lambda ifadeleri kullanmak üzere dönüştürüldü.Note that an await_expression cannot occur in most places within a query_expression, because those are syntactically transformed to use non-async lambda expressions.

Zaman uyumsuz bir işlevin içinde await tanımlayıcı olarak kullanılamaz.Inside of an async function, await cannot be used as an identifier. Bu nedenle, await ifadeleri ve tanımlayıcılar içeren çeşitli ifadeler arasında sözdizimsel belirsizlik yoktur.There is therefore no syntactic ambiguity between await-expressions and various expressions involving identifiers. Zaman uyumsuz işlevlerin dışında, await normal tanımlayıcı işlevi görür.Outside of async functions, await acts as a normal identifier.

Bir await_expression işleneni *Task _ olarak adlandırılır.The operand of an await_expression is called the *task _. _Await_expression * değerlendirildiği sırada tamamlanmamış veya tamamlanmamış bir zaman uyumsuz bir işlemi temsil eder.It represents an asynchronous operation that may or may not be complete at the time the _await_expression* is evaluated. Await işlecinin amacı, beklenen zaman uyumsuz işlevin yürütülmesini, bekleme görevi tamamlanana kadar askıya almak ve sonra sonucunu elde etmek için kullanılır.The purpose of the await operator is to suspend execution of the enclosing async function until the awaited task is complete, and then obtain its outcome.

Awasever ifadeleriAwaitable expressions

Await ifadesinin görevi için beklenen bir ifade olması gerekir.The task of an await expression is required to be awaitable. Aşağıdakilerden biri varsa bir ifade beklenebilir t :An expression t is awaitable if one of the following holds:

  • t derleme zamanı türündedir dynamict is of compile time type dynamic
  • t , hiçbir parametre olmadan ve hiçbir tür parametresi olmadan çağrılan, erişilebilir bir örnek veya genişletme yöntemine GetAwaiter ve A aşağıdakiler için aşağıdakilerin tümünün geri döndürdüğü bir dönüş türüne sahiptir:t has an accessible instance or extension method called GetAwaiter with no parameters and no type parameters, and a return type A for which all of the following hold:
    • A arabirimini uygular (bundan sonra System.Runtime.CompilerServices.INotifyCompletion INotifyCompletion breçekimi için olarak bilinirdi)A implements the interface System.Runtime.CompilerServices.INotifyCompletion (hereafter known as INotifyCompletion for brevity)
    • A, türünde erişilebilir, okunabilir bir örnek özelliğine sahiptir IsCompleted``boolA has an accessible, readable instance property IsCompleted of type bool
    • A``GetResultparametresi olmayan ve hiçbir tür parametresi olmayan erişilebilir bir örnek yöntemi vardırA has an accessible instance method GetResult with no parameters and no type parameters

Yönteminin amacı, GetAwaiter görev için bir *awaiter _ elde sağlamaktır.The purpose of the GetAwaiter method is to obtain an *awaiter _ for the task. Tür, A await ifadesi için _ awaiter türü* olarak adlandırılır.The type A is called the _ awaiter type* for the await expression.

IsCompletedÖzelliğin amacı görevin zaten tamamlanıp tamamlanmadığını belirlemektir.The purpose of the IsCompleted property is to determine if the task is already complete. Bu durumda, değerlendirmeyi askıya almanız gerekmez.If so, there is no need to suspend evaluation.

Yöntemin amacı, INotifyCompletion.OnCompleted göreve bir "devamlılık" System.Action atayacaksınız; Yani, görev tamamlandıktan sonra çağrılacak bir temsilci (tür).The purpose of the INotifyCompletion.OnCompleted method is to sign up a "continuation" to the task; i.e. a delegate (of type System.Action) that will be invoked once the task is complete.

Yönteminin amacı, GetResult tamamlandıktan sonra görevin sonucunu elde etmek için kullanılır.The purpose of the GetResult method is to obtain the outcome of the task once it is complete. Bu sonuç, büyük olasılıkla bir sonuç değeriyle birlikte başarılı bir şekilde tamamlanmayabilir veya yöntemi tarafından oluşturulan bir özel durum olabilir GetResult .This outcome may be successful completion, possibly with a result value, or it may be an exception which is thrown by the GetResult method.

Await ifadelerinin sınıflandırmasıClassification of await expressions

İfade, await t ifadesiyle aynı şekilde sınıflandırılır (t).GetAwaiter().GetResult() .The expression await t is classified the same way as the expression (t).GetAwaiter().GetResult(). Bu nedenle, öğesinin dönüş türü GetResult ise void await_expression hiçbir şey olarak sınıflandırılacaktır.Thus, if the return type of GetResult is void, the await_expression is classified as nothing. Void olmayan bir dönüş türü varsa T await_expression , türünde bir değer olarak sınıflandırılacaktır T .If it has a non-void return type T, the await_expression is classified as a value of type T.

Await ifadelerinin çalışma zamanı değerlendirmesiRuntime evaluation of await expressions

Çalışma zamanında, ifade await t aşağıdaki gibi değerlendirilir:At runtime, the expression await t is evaluated as follows:

  • İfade hesaplanarak bir awaiter a elde edilir (t).GetAwaiter() .An awaiter a is obtained by evaluating the expression (t).GetAwaiter().
  • , bool b İfadesi hesaplanarak elde edilir (a).IsCompleted .A bool b is obtained by evaluating the expression (a).IsCompleted.
  • İse b , false değerlendirme a , arabirimin System.Runtime.CompilerServices.ICriticalNotifyCompletion (örneğin, kısaltma için olarak bilinirdi) yapılıp yapılmayacağını bağlıdır ICriticalNotifyCompletion .If b is false then evaluation depends on whether a implements the interface System.Runtime.CompilerServices.ICriticalNotifyCompletion (hereafter known as ICriticalNotifyCompletion for brevity). Bu denetim bağlama zamanında yapılır; Yani, çalışma zamanında a derleme zamanı türü dynamic ve derleme zamanında, aksi halde.This check is done at binding time; i.e. at runtime if a has the compile time type dynamic, and at compile time otherwise. rSürdürme temsilcisini (Async işlevleri) göstermek için:Let r denote the resumption delegate (Async functions):
    • aUygulamaz ICriticalNotifyCompletion , ifade (a as (INotifyCompletion)).OnCompleted(r) değerlendirilir.If a does not implement ICriticalNotifyCompletion, then the expression (a as (INotifyCompletion)).OnCompleted(r) is evaluated.
    • aUygular ICriticalNotifyCompletion , ifade (a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r) değerlendirilir.If a does implement ICriticalNotifyCompletion, then the expression (a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r) is evaluated.
    • Değerlendirme daha sonra askıya alınır ve denetim zaman uyumsuz işlevin geçerli çağıranına döndürülür.Evaluation is then suspended, and control is returned to the current caller of the async function.
  • Hemen sonra ( b was true ) veya sürdürme temsilcisinin daha sonra çağrılması durumunda (varsa), b false ifade (a).GetResult() değerlendirilir.Either immediately after (if b was true), or upon later invocation of the resumption delegate (if b was false), the expression (a).GetResult() is evaluated. Değer döndürürse, bu değer await_expression sonucudur.If it returns a value, that value is the result of the await_expression. Aksi takdirde sonuç Nothing olur.Otherwise the result is nothing.

Bir awaiter 'ın Arabirim yöntemlerinin uygulanması INotifyCompletion.OnCompleted ve ICriticalNotifyCompletion.UnsafeOnCompleted temsilcinin r en çok bir kez çağrılabilir olmasına neden olması gerekir.An awaiter's implementation of the interface methods INotifyCompletion.OnCompleted and ICriticalNotifyCompletion.UnsafeOnCompleted should cause the delegate r to be invoked at most once. Aksi takdirde, kapsayan zaman uyumsuz işlevinin davranışı tanımsız olur.Otherwise, the behavior of the enclosing async function is undefined.

Aritmetik işleçlerArithmetic operators

*,, / , % + Ve - işleçleri aritmetik işleçler olarak adlandırılır.The *, /, %, +, and - operators are called the arithmetic operators.

multiplicative_expression
    : unary_expression
    | multiplicative_expression '*' unary_expression
    | multiplicative_expression '/' unary_expression
    | multiplicative_expression '%' unary_expression
    ;

additive_expression
    : multiplicative_expression
    | additive_expression '+' multiplicative_expression
    | additive_expression '-' multiplicative_expression
    ;

Aritmetik işlecin bir işleneni derleme zamanı türüne sahipse dynamic , ifade dinamik olarak bağlanır (dinamik bağlama).If an operand of an arithmetic operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). Bu durumda, ifadenin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, derleme zamanı türüne sahip olan işlenenleri çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir dynamic .In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

Çarpma işleciMultiplication operator

Formun bir işlemi için x * y , belirli bir operatör uygulamasını seçmek üzere ikili işleç aşırı yükleme çözümü (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x * y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış çarpma işleçleri aşağıda listelenmiştir.The predefined multiplication operators are listed below. İşleçleri, ve çarpımını hesaplar x y .The operators all compute the product of x and y.

  • Tamsayı çarpma:Integer multiplication:

    int operator *(int x, int y);
    uint operator *(uint x, uint y);
    long operator *(long x, long y);
    ulong operator *(ulong x, ulong y);
    

    Bir checked bağlamda, ürün sonuç türü aralığının dışındaysa, bir oluşturulur System.OverflowException .In a checked context, if the product is outside the range of the result type, a System.OverflowException is thrown. Bir unchecked bağlamda, taşmalar raporlanmaz ve sonuç türü aralığı dışındaki önemli yüksek sıralı bitler atılır.In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • Kayan nokta çarpma:Floating-point multiplication:

    float operator *(float x, float y);
    double operator *(double x, double y);
    

    Ürün, IEEE 754 aritmetik kurallarına göre hesaplanır.The product is computed according to the rules of IEEE 754 arithmetic. Aşağıdaki tabloda sıfır olmayan sonlu değerlerin, sıfırların, sonsuzların ve NaN’lerin tüm olası kombinasyonlarının sonuçları listelenmiştir.The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. Tabloda, x ve y pozitif sonlu değerlerdir.In the table, x and y are positive finite values. x * y değerinin sonucu z değeridir.z is the result of x * y. Sonuç, hedef türü için çok büyükse z sonsuzdur.If the result is too large for the destination type, z is infinity. Sonuç, hedef türü için çok küçükse z sıfırdır.If the result is too small for the destination type, z is zero.

    +y+y -y-y +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    +x+x +z+z -z-z +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    -x-x -z-z +z+z -0-0 +0+0 -INF-inf + INF+inf NaNNaN
    +0+0 +0+0 -0-0 +0+0 -0-0 NaNNaN NaNNaN NaNNaN
    -0-0 -0-0 +0+0 -0-0 +0+0 NaNNaN NaNNaN NaNNaN
    + INF+inf + INF+inf -INF-inf NaNNaN NaNNaN + INF+inf -INF-inf NaNNaN
    -INF-inf -INF-inf + INF+inf NaNNaN NaNNaN -INF-inf + INF+inf NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • Ondalık çarpma:Decimal multiplication:

    decimal operator *(decimal x, decimal y);
    

    Elde edilen değer, biçimde temsil etmek için çok büyükse decimal , bir oluşturulur System.OverflowException .If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. Sonuç değeri, biçimde temsil edilebilmesi için çok küçük ise decimal , sonuç sıfırdır.If the result value is too small to represent in the decimal format, the result is zero. Sonucun ölçeği, herhangi bir yuvarlamadan önce, iki işlenenin ölçeklerinin toplamıdır.The scale of the result, before any rounding, is the sum of the scales of the two operands.

    Ondalık çarpma, türündeki çarpma işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Decimal multiplication is equivalent to using the multiplication operator of type System.Decimal.

Bölme işleciDivision operator

Formun bir işlemi için x / y , belirli bir operatör uygulamasını seçmek üzere ikili işleç aşırı yükleme çözümü (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x / y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış bölüm işleçleri aşağıda listelenmiştir.The predefined division operators are listed below. İşleçleri tüm ve bölümünü hesaplar x y .The operators all compute the quotient of x and y.

  • Tamsayı bölme:Integer division:

    int operator /(int x, int y);
    uint operator /(uint x, uint y);
    long operator /(long x, long y);
    ulong operator /(ulong x, ulong y);
    

    Sağ işlenenin değeri sıfırsa, bir System.DivideByZeroException atılır.If the value of the right operand is zero, a System.DivideByZeroException is thrown.

    Bölme sonucu sıfıra doğru yuvarlar.The division rounds the result towards zero. Bu nedenle, sonucun mutlak değeri, iki işlenenin alanının mutlak değerinden küçük veya ona eşit olan en büyük olası tamsayıdır.Thus the absolute value of the result is the largest possible integer that is less than or equal to the absolute value of the quotient of the two operands. İki işlenen iki işlenen de ters işaret sahibi olduğunda, sonuç sıfır veya pozitif, sıfır veya negatif olur.The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs.

    Sol işlenen en küçük gösterilemeyen int veya long değerde ise ve sağ işlenen ise -1 , bir taşma oluşur.If the left operand is the smallest representable int or long value and the right operand is -1, an overflow occurs. Bir checked bağlamda bu, bir System.ArithmeticException (veya alt sınıfın) oluşturulmasına neden olur.In a checked context, this causes a System.ArithmeticException (or a subclass thereof) to be thrown. Bir unchecked bağlamda, bir System.ArithmeticException (veya bir alt sınıfın) oluşturulup oluşturulmayacağını ya da taşma değeri sol işlenenin elde edilen değerle bildirilmeden sonra, uygulama tarafından tanımlanır.In an unchecked context, it is implementation-defined as to whether a System.ArithmeticException (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.

  • Kayan nokta bölmesi:Floating-point division:

    float operator /(float x, float y);
    double operator /(double x, double y);
    

    Bu bölüm, IEEE 754 aritmetiğinin kurallarına göre hesaplanır.The quotient is computed according to the rules of IEEE 754 arithmetic. Aşağıdaki tabloda sıfır olmayan sonlu değerlerin, sıfırların, sonsuzların ve NaN’lerin tüm olası kombinasyonlarının sonuçları listelenmiştir.The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. Tabloda, x ve y pozitif sonlu değerlerdir.In the table, x and y are positive finite values. x / y değerinin sonucu z değeridir.z is the result of x / y. Sonuç, hedef türü için çok büyükse z sonsuzdur.If the result is too large for the destination type, z is infinity. Sonuç, hedef türü için çok küçükse z sıfırdır.If the result is too small for the destination type, z is zero.

    +y+y -y-y +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    +x+x +z+z -z-z + INF+inf -INF-inf +0+0 -0-0 NaNNaN
    -x-x -z-z +z+z -INF-inf + INF+inf -0-0 +0+0 NaNNaN
    +0+0 +0+0 -0-0 NaNNaN NaNNaN +0+0 -0-0 NaNNaN
    -0-0 -0-0 +0+0 NaNNaN NaNNaN -0-0 +0+0 NaNNaN
    + INF+inf + INF+inf -INF-inf + INF+inf -INF-inf NaNNaN NaNNaN NaNNaN
    -INF-inf -INF-inf + INF+inf -INF-inf + INF+inf NaNNaN NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • Ondalık bölme:Decimal division:

    decimal operator /(decimal x, decimal y);
    

    Sağ işlenenin değeri sıfırsa, bir System.DivideByZeroException atılır.If the value of the right operand is zero, a System.DivideByZeroException is thrown. Elde edilen değer, biçimde temsil etmek için çok büyükse decimal , bir oluşturulur System.OverflowException .If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. Sonuç değeri, biçimde temsil edilebilmesi için çok küçük ise decimal , sonuç sıfırdır.If the result value is too small to represent in the decimal format, the result is zero. Sonucun ölçeği, en yakın gösterilebilir tablo ondalık değerine eşit olan bir sonucu doğru matematik sonucuyla koruyacak en küçük ölçeğe neden olur.The scale of the result is the smallest scale that will preserve a result equal to the nearest representable decimal value to the true mathematical result.

    Ondalık bölüm, türündeki Bölme işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Decimal division is equivalent to using the division operator of type System.Decimal.

Kalan işleçRemainder operator

Formun bir işlemi için x % y , belirli bir operatör uygulamasını seçmek üzere ikili işleç aşırı yükleme çözümü (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x % y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış geri kalan işleçler aşağıda listelenmiştir.The predefined remainder operators are listed below. İşleçler, ve arasındaki bölmenin geri kalanını hesaplar x y .The operators all compute the remainder of the division between x and y.

  • Tamsayı geri kalanı:Integer remainder:

    int operator %(int x, int y);
    uint operator %(uint x, uint y);
    long operator %(long x, long y);
    ulong operator %(ulong x, ulong y);
    

    Sonucu x % y tarafından üretilen değerdir x - (x / y) * y .The result of x % y is the value produced by x - (x / y) * y. ySıfırsa, bir oluşturulur System.DivideByZeroException .If y is zero, a System.DivideByZeroException is thrown.

    Sol işlenen en küçük int veya long değer ise ve sağ işlenen ise -1 , bir oluşturulur System.OverflowException .If the left operand is the smallest int or long value and the right operand is -1, a System.OverflowException is thrown. Hiçbir durumda, x % y x / y özel durum oluşturmayan bir özel durum oluşturur.In no case does x % y throw an exception where x / y would not throw an exception.

  • Kayan nokta kalanı:Floating-point remainder:

    float operator %(float x, float y);
    double operator %(double x, double y);
    

    Aşağıdaki tabloda sıfır olmayan sonlu değerlerin, sıfırların, sonsuzların ve NaN’lerin tüm olası kombinasyonlarının sonuçları listelenmiştir.The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. Tabloda, x ve y pozitif sonlu değerlerdir.In the table, x and y are positive finite values. z , x % y ve ' nin sonucu olarak hesaplanır x - n * y ; burada, ' n den küçük veya buna eşit olan en büyük tamsayıdır x / y .z is the result of x % y and is computed as x - n * y, where n is the largest possible integer that is less than or equal to x / y. Bu geri kalanı hesaplama yöntemi, tamsayı işlenenleri için kullanılan ile benzerdir, ancak IEEE 754 tanımından (yani n , en yakın tamsayı x / y ) farklıdır.This method of computing the remainder is analogous to that used for integer operands, but differs from the IEEE 754 definition (in which n is the integer closest to x / y).

    +y+y -y-y +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    +x+x +z+z +z+z NaNNaN NaNNaN xx xx NaNNaN
    -x-x -z-z -z-z NaNNaN NaNNaN -x-x -x-x NaNNaN
    +0+0 +0+0 +0+0 NaNNaN NaNNaN +0+0 +0+0 NaNNaN
    -0-0 -0-0 -0-0 NaNNaN NaNNaN -0-0 -0-0 NaNNaN
    + INF+inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
    -INF-inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • Ondalık kalan:Decimal remainder:

    decimal operator %(decimal x, decimal y);
    

    Sağ işlenenin değeri sıfırsa, bir System.DivideByZeroException atılır.If the value of the right operand is zero, a System.DivideByZeroException is thrown. Sonucun ölçeği, herhangi bir yuvarlamadan önce, iki işlenenin ölçeklerinin daha büyük olması ve sıfır olmayan bir değer ise, ile aynı ' dır x .The scale of the result, before any rounding, is the larger of the scales of the two operands, and the sign of the result, if non-zero, is the same as that of x.

    Decimal geri kalanı, türündeki kalan işlecin kullanılmasıyla eşdeğerdir System.Decimal .Decimal remainder is equivalent to using the remainder operator of type System.Decimal.

Toplama işleciAddition operator

Formun bir işlemi için x + y , belirli bir operatör uygulamasını seçmek üzere ikili işleç aşırı yükleme çözümü (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x + y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış ekleme işleçleri aşağıda listelenmiştir.The predefined addition operators are listed below. Sayısal ve sabit listesi türlerinde, önceden tanımlanmış ekleme işleçleri iki işlenenin toplamını hesaplar.For numeric and enumeration types, the predefined addition operators compute the sum of the two operands. Bir veya her iki işlenen de dize türünde olduğunda, önceden tanımlanmış toplama işleçleri işlenen dize gösterimini birleştirir.When one or both operands are of type string, the predefined addition operators concatenate the string representation of the operands.

  • Tamsayı ekleme:Integer addition:

    int operator +(int x, int y);
    uint operator +(uint x, uint y);
    long operator +(long x, long y);
    ulong operator +(ulong x, ulong y);
    

    Bir checked bağlamda, Sum sonuç türü aralığının dışındaysa, bir System.OverflowException atılır.In a checked context, if the sum is outside the range of the result type, a System.OverflowException is thrown. Bir unchecked bağlamda, taşmalar raporlanmaz ve sonuç türü aralığı dışındaki önemli yüksek sıralı bitler atılır.In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • Kayan nokta ekleme:Floating-point addition:

    float operator +(float x, float y);
    double operator +(double x, double y);
    

    Toplam, IEEE 754 aritmetiğinin kurallarına göre hesaplanır.The sum is computed according to the rules of IEEE 754 arithmetic. Aşağıdaki tabloda sıfır olmayan sonlu değerlerin, sıfırların, sonsuzların ve NaN’lerin tüm olası kombinasyonlarının sonuçları listelenmiştir.The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. Tabloda, x ve y sıfır olmayan sonlu değerlerdir ve z, x + y işleminin sonucudur.In the table, x and y are nonzero finite values, and z is the result of x + y. x ve y aynı büyüklüğe, ancak ters işaretlere sahipse z, pozitif sıfırdır.If x and y have the same magnitude but opposite signs, z is positive zero. x + yHedef türünde temsil etmek için çok büyük ise, z aynı işarete sahip bir sonsuzluk olur x + y .If x + y is too large to represent in the destination type, z is an infinity with the same sign as x + y.

    yy +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    xx zz xx xx + INF+inf -INF-inf NaNNaN
    +0+0 yy +0+0 +0+0 + INF+inf -INF-inf NaNNaN
    -0-0 yy +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    + INF+inf + INF+inf + INF+inf + INF+inf + INF+inf NaNNaN NaNNaN
    -INF-inf -INF-inf -INF-inf -INF-inf NaNNaN -INF-inf NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • Ondalık ekleme:Decimal addition:

    decimal operator +(decimal x, decimal y);
    

    Elde edilen değer, biçimde temsil etmek için çok büyükse decimal , bir oluşturulur System.OverflowException .If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. Sonucun ölçeği, herhangi bir yuvarlamadan önce, iki işlenenin ölçeklendirilmesine göre daha büyüktür.The scale of the result, before any rounding, is the larger of the scales of the two operands.

    Ondalık ekleme, türünün toplama işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Decimal addition is equivalent to using the addition operator of type System.Decimal.

  • Numaralandırma ekleme.Enumeration addition. Her numaralandırma türü örtük olarak aşağıdaki önceden tanımlanmış işleçleri sağlar, burada E numaralandırma türüdür ve U temel alınan türüdür E :Every enumeration type implicitly provides the following predefined operators, where E is the enum type, and U is the underlying type of E:

    E operator +(E x, U y);
    E operator +(U x, E y);
    

    Çalışma zamanında bu işleçler tam olarak olarak değerlendirilir (E)((U)x + (U)y) .At run-time these operators are evaluated exactly as (E)((U)x + (U)y).

  • Dize birleştirme:String concatenation:

    string operator +(string x, string y);
    string operator +(string x, object y);
    string operator +(object x, string y);
    

    İkili işlecinin bu aşırı yüklemeleri + dize birleştirmesi gerçekleştirir.These overloads of the binary + operator perform string concatenation. Dize birleştirme işleneni ise null boş bir dize değiştirilir.If an operand of string concatenation is null, an empty string is substituted. Aksi halde, dize olmayan herhangi bir bağımsız değişken, türden devralınan sanal yöntemi çağırarak dize gösterimine dönüştürülür ToString object .Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. ToStringDönerse null boş bir dize değiştirilir.If ToString returns null, an empty string is substituted.

    using System;
    
    class Test
    {
        static void Main() {
            string s = null;
            Console.WriteLine("s = >" + s + "<");        // displays s = ><
            int i = 1;
            Console.WriteLine("i = " + i);               // displays i = 1
            float f = 1.2300E+15F;
            Console.WriteLine("f = " + f);               // displays f = 1.23E+15
            decimal d = 2.900m;
            Console.WriteLine("d = " + d);               // displays d = 2.900
        }
    }
    

    Dize birleştirme işlecinin sonucu, sol işlenenin karakterlerinden ve ardından sağ işlenenin karakterlerinden oluşan bir dizedir. Dize birleştirme işleci hiçbir şekilde bir null değer döndürmez. System.OutOfMemoryExceptionElde edilen dizeyi ayırmak için yeterli kullanılabilir bellek yoksa bir durum oluşabilir.A System.OutOfMemoryException may be thrown if there is not enough memory available to allocate the resulting string.

  • Temsilci birleşimi.Delegate combination. Her temsilci türü örtük olarak aşağıdaki önceden tanımlı işleci sağlar, burada D temsilci türüdür:Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

    D operator +(D x, D y);
    

    İkili + işleç, her iki işlenen de bazı temsilci türleri olduğunda temsilci bileşimini gerçekleştirir D .The binary + operator performs delegate combination when both operands are of some delegate type D. (İşlenenler farklı temsilci türlerine sahip ise, bir bağlama zamanı hatası oluşur.) İlk işlenen ise, null işlemin sonucu ikinci işlenenin değeridir (aynı zamanda olsa bile null ).(If the operands have different delegate types, a binding-time error occurs.) If the first operand is null, the result of the operation is the value of the second operand (even if that is also null). Aksi takdirde, ikinci işlenen ise null işlemin sonucu ilk işlenenin değeridir.Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. Aksi takdirde, işlem sonucu çağrıldığında, ilk işleneni çağırır ve sonra ikinci işleneni çağıran yeni bir temsilci örneğidir.Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand. Temsilci birleşimi örnekleri için bkz. çıkarma işleci ve temsilci çağrısı.For examples of delegate combination, see Subtraction operator and Delegate invocation. System.DelegateBir temsilci türü olmadığından, operator  + için tanımlı değil.Since System.Delegate is not a delegate type, operator + is not defined for it.

Çıkarma işleciSubtraction operator

Formun bir işlemi için x - y , belirli bir operatör uygulamasını seçmek üzere ikili işleç aşırı yükleme çözümü (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x - y, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış çıkarma işleçleri aşağıda listelenmiştir.The predefined subtraction operators are listed below. Tüm işleçler, y öğesinden çıkar x .The operators all subtract y from x.

  • Tamsayı çıkarma:Integer subtraction:

    int operator -(int x, int y);
    uint operator -(uint x, uint y);
    long operator -(long x, long y);
    ulong operator -(ulong x, ulong y);
    

    Bir checked bağlamda, fark sonuç türü aralığının dışındaysa, bir oluşturulur System.OverflowException .In a checked context, if the difference is outside the range of the result type, a System.OverflowException is thrown. Bir unchecked bağlamda, taşmalar raporlanmaz ve sonuç türü aralığı dışındaki önemli yüksek sıralı bitler atılır.In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

  • Kayan nokta çıkarma:Floating-point subtraction:

    float operator -(float x, float y);
    double operator -(double x, double y);
    

    Aradaki fark, IEEE 754 aritmetiğinin kurallarına göre hesaplanır.The difference is computed according to the rules of IEEE 754 arithmetic. Aşağıdaki tabloda, sıfır dışında sınırlı değer, sıfır, sonsuz ve NaNs 'ın tüm olası birleşimlerinin sonuçları listelenmiştir.The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaNs. Tabloda, x ve y sıfır olmayan sonlu değerlerdir ve z, x - y işleminin sonucudur.In the table, x and y are nonzero finite values, and z is the result of x - y. x ve y eşitse z pozitif sıfırdır.If x and y are equal, z is positive zero. x - yHedef türünde temsil etmek için çok büyük ise, z aynı işarete sahip bir sonsuzluk olur x - y .If x - y is too large to represent in the destination type, z is an infinity with the same sign as x - y.

    yy +0+0 -0-0 + INF+inf -INF-inf NaNNaN
    xx zz xx xx -INF-inf + INF+inf NaNNaN
    +0+0 -y-y +0+0 +0+0 -INF-inf + INF+inf NaNNaN
    -0-0 -y-y -0-0 +0+0 -INF-inf + INF+inf NaNNaN
    + INF+inf + INF+inf + INF+inf + INF+inf NaNNaN + INF+inf NaNNaN
    -INF-inf -INF-inf -INF-inf -INF-inf -INF-inf NaNNaN NaNNaN
    NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
  • Ondalık çıkarma:Decimal subtraction:

    decimal operator -(decimal x, decimal y);
    

    Elde edilen değer, biçimde temsil etmek için çok büyükse decimal , bir oluşturulur System.OverflowException .If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. Sonucun ölçeği, herhangi bir yuvarlamadan önce, iki işlenenin ölçeklendirilmesine göre daha büyüktür.The scale of the result, before any rounding, is the larger of the scales of the two operands.

    Decimal çıkarma, türünün çıkarma işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Decimal subtraction is equivalent to using the subtraction operator of type System.Decimal.

  • Sabit Listesi çıkarma.Enumeration subtraction. Her numaralandırma türü örtük olarak aşağıdaki önceden tanımlı işleci sağlar, burada E numaralandırma türüdür ve U temel alınan türüdür E :Every enumeration type implicitly provides the following predefined operator, where E is the enum type, and U is the underlying type of E:

    U operator -(E x, E y);
    

    Bu işleç tam olarak olarak değerlendirilir (U)((U)x - (U)y) .This operator is evaluated exactly as (U)((U)x - (U)y). Diğer bir deyişle işleç, ve değerlerinin sırası arasındaki farkı hesaplar ve x y sonucun türü, numaralandırmanın temel alınan türüdür.In other words, the operator computes the difference between the ordinal values of x and y, and the type of the result is the underlying type of the enumeration.

    E operator -(E x, U y);
    

    Bu işleç tam olarak olarak değerlendirilir (E)((U)x - y) .This operator is evaluated exactly as (E)((U)x - y). Diğer bir deyişle işleci, numaralandırmanın temel alınan türünden bir değeri çıkartır ve sabit listesinin bir değerini çıkarır.In other words, the operator subtracts a value from the underlying type of the enumeration, yielding a value of the enumeration.

  • Temsilci kaldırma.Delegate removal. Her temsilci türü örtük olarak aşağıdaki önceden tanımlı işleci sağlar, burada D temsilci türüdür:Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

    D operator -(D x, D y);
    

    İkili - işleç, her iki işlenen de bazı temsilci türleri olduğunda temsilci kaldırma işlemini gerçekleştirir D .The binary - operator performs delegate removal when both operands are of some delegate type D. İşlenenler farklı temsilci türlerine sahip ise, bir bağlama zamanı hatası oluşur.If the operands have different delegate types, a binding-time error occurs. İlk işlenen ise, null işlemin sonucu olur null .If the first operand is null, the result of the operation is null. Aksi takdirde, ikinci işlenen ise null işlemin sonucu ilk işlenenin değeridir.Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. Aksi halde, her iki işlenen de bir veya daha fazla girişe sahip çağrı listelerini (temsilci bildirimleri) temsil eder ve sonuç, ikinci işlenenin listesinin ilk olarak doğru bir bitişik alt listesi olması şartıyla, ikinci işlenenin listesini içeren ilk işlenenin listesinden oluşan yeni bir çağırma listesidir.Otherwise, both operands represent invocation lists (Delegate declarations) having one or more entries, and the result is a new invocation list consisting of the first operand's list with the second operand's entries removed from it, provided the second operand's list is a proper contiguous sublist of the first's. (Alt liste eşitliğini belirleyebilmek için, karşılık gelen girişler, temsilci eşitlik işleci (temsilci eşitlik işleçleri) ile karşılaştırılır.) Aksi halde, sonuç sol işlenenin değeridir.(To determine sublist equality, corresponding entries are compared as for the delegate equality operator (Delegate equality operators).) Otherwise, the result is the value of the left operand. İşlemde işlenen listelerden hiçbiri değiştirilmez.Neither of the operands' lists is changed in the process. İkinci işlenenin listesi, ilk işlenen listesindeki bitişik girdilerin birden çok alt listesiyle eşleşiyorsa, bitişik girdilerin en sağ eşleşen alt listesi kaldırılır.If the second operand's list matches multiple sublists of contiguous entries in the first operand's list, the right-most matching sublist of contiguous entries is removed. Kaldırma işlemi boş bir liste ile sonuçlanırsa sonuç olur null .If removal results in an empty list, the result is null. Örnek:For example:

    delegate void D(int x);
    
    class C
    {
        public static void M1(int i) { /* ... */ }
        public static void M2(int i) { /* ... */ }
    }
    
    class Test
    {
        static void Main() { 
            D cd1 = new D(C.M1);
            D cd2 = new D(C.M2);
            D cd3 = cd1 + cd2 + cd2 + cd1;   // M1 + M2 + M2 + M1
            cd3 -= cd1;                      // => M1 + M2 + M2
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd1 + cd2;                // => M2 + M1
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd2 + cd2;                // => M1 + M1
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd2 + cd1;                // => M1 + M2
    
            cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
            cd3 -= cd1 + cd1;                // => M1 + M2 + M2 + M1
        }
    }
    

Kaydırma işleçleriShift operators

<<Ve >> işleçleri, bit kaydırma işlemlerini gerçekleştirmek için kullanılır.The << and >> operators are used to perform bit shifting operations.

shift_expression
    : additive_expression
    | shift_expression '<<' additive_expression
    | shift_expression right_shift additive_expression
    ;

Bir shift_expression işleneni derleme zamanı türüne sahipse dynamic , ifade dinamik olarak bağlanır (dinamik bağlama).If an operand of a shift_expression has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). Bu durumda, ifadenin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, derleme zamanı türüne sahip olan işlenenleri çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir dynamic .In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

Ya da bir işlem için x << count x >> count , ikili işleç aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümlemesi) belirli bir operatör uygulamasını seçmek için uygulanır.For an operation of the form x << count or x >> count, binary operator overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Aşırı yüklenmiş bir kaydırma işleci bildirirken, İlk işlenenin türü her zaman işleç bildirimini içeren sınıf veya yapı olmalıdır ve ikinci işlenenin türü her zaman olmalıdır int .When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration, and the type of the second operand must always be int.

Önceden tanımlanmış kaydırma işleçleri aşağıda listelenmiştir.The predefined shift operators are listed below.

  • Sola kaydır:Shift left:

    int operator <<(int x, int count);
    uint operator <<(uint x, int count);
    long operator <<(long x, int count);
    ulong operator <<(ulong x, int count);
    

    <<İşleci, x aşağıda açıklandığı gibi hesaplanan sayıda bit ile sola kayar.The << operator shifts x left by a number of bits computed as described below.

    Sonuç türü aralığının dışındaki yüksek sıralı bitler x atılır, kalan bitler sola kaydıralınır ve düşük sıralı boş bit konumları sıfır olarak ayarlanır.The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero.

  • Sağa kaydır:Shift right:

    int operator >>(int x, int count);
    uint operator >>(uint x, int count);
    long operator >>(long x, int count);
    ulong operator >>(ulong x, int count);
    

    >>İşleci, x aşağıda açıklandığı gibi hesaplanan sayıda bit ile sağa kayar.The >> operator shifts x right by a number of bits computed as described below.

    xVeya türünde olduğunda int long , düşük sıralı bitler x atılır, kalan bitler sağa kaydıralınır ve yüksek sıralı boş bit konumları sıfır olarak ayarlanır ve negatifse, x bir olarak ayarlanır x .When x is of type int or long, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative.

    xVeya türünde olduğunda uint ulong , düşük sıralı bitleri x atılır, kalan bitler sağa kaydıralınır ve yüksek sıralı boş bit konumları sıfır olarak ayarlanır.When x is of type uint or ulong, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.

Önceden tanımlanmış işleçler için, kaydırma yapılacak bit sayısı şu şekilde hesaplanır:For the predefined operators, the number of bits to shift is computed as follows:

  • Türü x int veya olduğunda uint , kaydırma sayısı düşük sıralı beş bit tarafından verilir count .When the type of x is int or uint, the shift count is given by the low-order five bits of count. Diğer bir deyişle, kaydırma sayısı öğesinden hesaplanır count & 0x1F .In other words, the shift count is computed from count & 0x1F.
  • Türü x long veya olduğunda ulong , kaydırma sayısı alt-sırası altı biti tarafından verilir count .When the type of x is long or ulong, the shift count is given by the low-order six bits of count. Diğer bir deyişle, kaydırma sayısı öğesinden hesaplanır count & 0x3F .In other words, the shift count is computed from count & 0x3F.

Sonuç kaydırma sayısı sıfırsa, kaydırma işleçleri yalnızca değerini döndürür x .If the resulting shift count is zero, the shift operators simply return the value of x.

Shift işlemleri hiçbir şekilde taşmaya neden olmaz ve checked ve bağlamlarda aynı sonuçları üretir unchecked .Shift operations never cause overflows and produce the same results in checked and unchecked contexts.

İşlecin sol işleneni >> işaretli bir integral türünde olduğunda, işleç, işlenenin en önemli bit (işaret biti) değerinde bir aritmetik kaydırma gerçekleştirir ve yüksek sıralı boş bit konumlarına yayılır.When the left operand of the >> operator is of a signed integral type, the operator performs an arithmetic shift right wherein the value of the most significant bit (the sign bit) of the operand is propagated to the high-order empty bit positions. İşlecin sol işleneni >> işaretsiz bir integral türünde olduğunda, işleç yüksek sıralı boş bit konumlarında her zaman sıfır olarak ayarlanmış bir mantıksal kaydırma gerçekleştirir.When the left operand of the >> operator is of an unsigned integral type, the operator performs a logical shift right wherein high-order empty bit positions are always set to zero. İşlenen türünden çıkarılan ' nin ters işlemini gerçekleştirmek için, açık atamalar kullanılabilir.To perform the opposite operation of that inferred from the operand type, explicit casts can be used. Örneğin, x türünde bir değişkense int , işlem, unchecked((int)((uint)x >> y)) sağ bir mantıksal kaydırma gerçekleştirir x .For example, if x is a variable of type int, the operation unchecked((int)((uint)x >> y)) performs a logical shift right of x.

İlişkisel ve tür testi işleçleriRelational and type-testing operators

,,,,, == != < > <= >= is Ve as işleçleri ilişkisel ve tür testi işleçleri olarak adlandırılır.The ==, !=, <, >, <=, >=, is and as operators are called the relational and type-testing operators.

relational_expression
    : shift_expression
    | relational_expression '<' shift_expression
    | relational_expression '>' shift_expression
    | relational_expression '<=' shift_expression
    | relational_expression '>=' shift_expression
    | relational_expression 'is' type
    | relational_expression 'as' type
    ;

equality_expression
    : relational_expression
    | equality_expression '==' relational_expression
    | equality_expression '!=' relational_expression
    ;

isİşleci ,,,,,, işleç ve as işleci içinde açıklanmıştır as . The is operator is described in The is operator and the as operator is described in The as operator.

==,, != , < > <= Ve >= işleçleri karşılaştırma işleçleridir.The ==, !=, <, >, <= and >= operators are comparison operators.

Karşılaştırma işlecinin bir işleneni derleme zamanı türüne sahipse dynamic , ifade dinamik olarak bağlanır (dinamik bağlama).If an operand of a comparison operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). Bu durumda, ifadenin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, derleme zamanı türüne sahip olan işlenenleri çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir dynamic .In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

Op bir karşılaştırma operatörü olduğu form op 'nin bir işlemi için x y , belirli bir operatör uygulamasını seçmek üzere aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümlemesi) uygulanır. For an operation of the form x op y, where op is a comparison operator, overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış karşılaştırma işleçleri aşağıdaki bölümlerde açıklanmıştır.The predefined comparison operators are described in the following sections. Önceden tanımlanmış tüm karşılaştırma işleçleri bool , aşağıdaki tabloda açıklandığı gibi türünün bir sonucunu döndürür.All predefined comparison operators return a result of type bool, as described in the following table.

İşlemOperation SonuçResult
x == y true``xeşitse y , false Aksi takdirdetrue if x is equal to y, false otherwise
x != y true``xeşit değilse y , false tersi durumdatrue if x is not equal to y, false otherwise
x < y x değeri y değerinden küçükse true, değilse falsetrue if x is less than y, false otherwise
x > y x değeri y değerinden büyükse true, değilse falsetrue if x is greater than y, false otherwise
x <= y x değeri y değerinden küçükse veya bu değere eşitse true, değilse falsetrue if x is less than or equal to y, false otherwise
x >= y x değeri y değerinden büyükse veya bu değere eşitse true, değilse falsetrue if x is greater than or equal to y, false otherwise

Tamsayı karşılaştırma işleçleriInteger comparison operators

Önceden tanımlanmış tamsayı karşılaştırma işleçleri şunlardır:The predefined integer comparison operators are:

bool operator ==(int x, int y);
bool operator ==(uint x, uint y);
bool operator ==(long x, long y);
bool operator ==(ulong x, ulong y);

bool operator !=(int x, int y);
bool operator !=(uint x, uint y);
bool operator !=(long x, long y);
bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);
bool operator <(uint x, uint y);
bool operator <(long x, long y);
bool operator <(ulong x, ulong y);

bool operator >(int x, int y);
bool operator >(uint x, uint y);
bool operator >(long x, long y);
bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);
bool operator <=(uint x, uint y);
bool operator <=(long x, long y);
bool operator <=(ulong x, ulong y);

bool operator >=(int x, int y);
bool operator >=(uint x, uint y);
bool operator >=(long x, long y);
bool operator >=(ulong x, ulong y);

Bu işleçlerin her biri, iki tamsayı işleneninin sayısal değerlerini karşılaştırır ve bool belirli bir ilişkinin veya olduğunu gösteren bir değer döndürür true false .Each of these operators compares the numeric values of the two integer operands and returns a bool value that indicates whether the particular relation is true or false.

Kayan nokta karşılaştırma işleçleriFloating-point comparison operators

Önceden tanımlanmış kayan nokta karşılaştırma işleçleri şunlardır:The predefined floating-point comparison operators are:

bool operator ==(float x, float y);
bool operator ==(double x, double y);

bool operator !=(float x, float y);
bool operator !=(double x, double y);

bool operator <(float x, float y);
bool operator <(double x, double y);

bool operator >(float x, float y);
bool operator >(double x, double y);

bool operator <=(float x, float y);
bool operator <=(double x, double y);

bool operator >=(float x, float y);
bool operator >=(double x, double y);

İşleçler, işlenenleri IEEE 754 standardının kurallarına göre karşılaştırır:The operators compare the operands according to the rules of the IEEE 754 standard:

  • Her iki işlenen de NaN ise, sonuç, false bunun dışındaki tüm işleçlere yöneliktir != true .If either operand is NaN, the result is false for all operators except !=, for which the result is true. Her iki işlenen için x != y her zaman aynı sonucu üretir !(x == y) .For any two operands, x != y always produces the same result as !(x == y). Ancak, bir veya her iki işlenen Nan olduğunda,, < , > <= ve >= işleçleri ters işlecin mantıksal değille aynı sonuçları oluşturmaz.However, when one or both operands are NaN, the <, >, <=, and >= operators do not produce the same results as the logical negation of the opposite operator. Örneğin, ve eğer NaN ise x , y x < y false , ancak olur !(x >= y) true .For example, if either of x and y is NaN, then x < y is false, but !(x >= y) is true.

  • Hiçbir işlenen NaN olmadığında, işleçler iki kayan nokta işleneninin değerlerini sıralamaya göre karşılaştırırWhen neither operand is NaN, the operators compare the values of the two floating-point operands with respect to the ordering

    -inf < -max < ... < -min < -0.0 == +0.0 < +min < ... < +max < +inf
    

    Burada min ve, max verilen kayan nokta biçiminde temsil edilebilecek en küçük ve en büyük pozitif sınırlı değerlerdir.where min and max are the smallest and largest positive finite values that can be represented in the given floating-point format. Bu sıralamanın önemli etkileri şunlardır:Notable effects of this ordering are:

    • Negatif ve pozitif sıfır değerleri eşit kabul edilir.Negative and positive zeros are considered equal.
    • Negatif sonsuzluk, diğer tüm değerlerden daha az kabul edilir, ancak başka bir negatif sonsuzya eşittir.A negative infinity is considered less than all other values, but equal to another negative infinity.
    • Pozitif sonsuzluk, diğer tüm değerlerden daha büyük sayılır, ancak başka bir pozitif sonsuzya eşittir.A positive infinity is considered greater than all other values, but equal to another positive infinity.

Ondalık karşılaştırma işleçleriDecimal comparison operators

Önceden tanımlanmış ondalık karşılaştırma işleçleri şunlardır:The predefined decimal comparison operators are:

bool operator ==(decimal x, decimal y);
bool operator !=(decimal x, decimal y);
bool operator <(decimal x, decimal y);
bool operator >(decimal x, decimal y);
bool operator <=(decimal x, decimal y);
bool operator >=(decimal x, decimal y);

Bu işleçlerin her biri, iki ondalık işlenenin sayısal değerlerini karşılaştırır ve bool belirli ilişkinin veya olduğunu belirten bir değer döndürür true false .Each of these operators compares the numeric values of the two decimal operands and returns a bool value that indicates whether the particular relation is true or false. Her ondalık karşılaştırma, türü karşılık gelen ilişkisel veya eşitlik işlecinin kullanılmasıyla eşdeğerdir System.Decimal .Each decimal comparison is equivalent to using the corresponding relational or equality operator of type System.Decimal.

Boole eşitlik işleçleriBoolean equality operators

Önceden tanımlanmış Boole eşitlik işleçleri şunlardır:The predefined boolean equality operators are:

bool operator ==(bool x, bool y);
bool operator !=(bool x, bool y);

Her ikisi de ve, == ve ise olur true x y true x y false .The result of == is true if both x and y are true or if both x and y are false. Aksi takdirde, sonuç olur false .Otherwise, the result is false.

Her ikisi de ve, != ve ise olur false x y true x y false .The result of != is false if both x and y are true or if both x and y are false. Aksi takdirde, sonuç olur true .Otherwise, the result is true. İşlenenler tür olduğunda bool != işleç, işleçle aynı sonucu üretir ^ .When the operands are of type bool, the != operator produces the same result as the ^ operator.

Sabit Listesi karşılaştırma işleçleriEnumeration comparison operators

Her numaralandırma türü örtük olarak aşağıdaki önceden tanımlı karşılaştırma işleçlerini sağlar:Every enumeration type implicitly provides the following predefined comparison operators:

bool operator ==(E x, E y);
bool operator !=(E x, E y);
bool operator <(E x, E y);
bool operator >(E x, E y);
bool operator <=(E x, E y);
bool operator >=(E x, E y);

Bir x op y x numaralandırma türünün temel alınan bir tür ile değerlendirilmesi, nerede ve nerede olduğu y E U ve op karşılaştırma işleçlerinden biri olan, tam olarak değerlendirilme sonucu ((U)x) op ((U)y) .The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the comparison operators, is exactly the same as evaluating ((U)x) op ((U)y). Diğer bir deyişle, numaralandırma türü karşılaştırma işleçleri yalnızca iki işlenenin temel alınan integral değerlerini karşılaştırmaktır.In other words, the enumeration type comparison operators simply compare the underlying integral values of the two operands.

Başvuru türü eşitlik işleçleriReference type equality operators

Önceden tanımlanmış başvuru türü eşitlik işleçleri şunlardır:The predefined reference type equality operators are:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

İşleçler, eşitlik veya eşitlik için iki başvuruyu karşılaştırmanın sonucunu döndürür.The operators return the result of comparing the two references for equality or non-equality.

Önceden tanımlanmış başvuru türü eşitlik işleçleri türündeki işlenenleri kabul ettiğinde object , bunlar uygulanabilir ve üyeleri bildirmiyor tüm türler için geçerlidir operator == operator != .Since the predefined reference type equality operators accept operands of type object, they apply to all types that do not declare applicable operator == and operator != members. Buna karşılık, geçerli kullanıcı tanımlı eşitlik işleçleri, önceden tanımlanmış başvuru türü eşitlik işleçlerini etkin bir şekilde gizler.Conversely, any applicable user-defined equality operators effectively hide the predefined reference type equality operators.

Önceden tanımlanmış başvuru türü eşitlik işleçleri aşağıdakilerden birini gerektirir:The predefined reference type equality operators require one of the following:

  • Her iki işlenen de reference_type veya sabit değer olarak bilinen bir türün değeridir null .Both operands are a value of a type known to be a reference_type or the literal null. Ayrıca, bir açık başvuru dönüştürmesi (açık başvuru dönüştürmeleri), herhangi bir işlenenin türünden diğer işlenenin türüne de sahiptir.Furthermore, an explicit reference conversion (Explicit reference conversions) exists from the type of either operand to the type of the other operand.
  • Bir işlenen, T T type_parameter olan ve diğer işlenen değişmez değer olan bir değerdir null .One operand is a value of type T where T is a type_parameter and the other operand is the literal null. Ayrıca T , değer türü kısıtlamasına sahip değildir.Furthermore T does not have the value type constraint.

Bu koşullardan biri doğru değilse, bir bağlama zamanı hatası oluşur.Unless one of these conditions are true, a binding-time error occurs. Bu kuralların önemli etkileri şunlardır:Notable implications of these rules are:

  • Bu, bağlama zamanında farklı oldukları bilinen iki başvuruyu karşılaştırmak için önceden tanımlanmış başvuru türü eşitlik işleçlerini kullanmanın bir bağlama zamanı hatasıdır.It is a binding-time error to use the predefined reference type equality operators to compare two references that are known to be different at binding-time. Örneğin, işlenenlerin bağlama zamanı türleri iki sınıf türü ise ve A B ne A de B diğeri bundan türetilmediği takdirde, iki işlenen aynı nesneye başvuruda bulunmak mümkün değildir.For example, if the binding-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. Bu nedenle, işlem bağlama zamanı hatası olarak değerlendirilir.Thus, the operation is considered a binding-time error.
  • Önceden tanımlanmış başvuru türü eşitlik işleçleri değer türü işlenenlerinin karşılaştırılabilmesi için izin vermez.The predefined reference type equality operators do not permit value type operands to be compared. Bu nedenle, bir struct türü kendi eşitlik işleçlerini bildirmediği için, bu yapı türünün değerlerini karşılaştırmak mümkün değildir.Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type.
  • Önceden tanımlanmış başvuru türü eşitlik işleçleri, işlenenleri için paketleme işlemlerine neden olmaz.The predefined reference type equality operators never cause boxing operations to occur for their operands. Yeni ayrılmış paketlenmiş örneklere yapılan başvuruların diğer tüm başvurulardan farklı olması gerektiğinden, bu tür kutulanabilir işlemleri gerçekleştirmek anlamlı değildir.It would be meaningless to perform such boxing operations, since references to the newly allocated boxed instances would necessarily differ from all other references.
  • Bir tür parametre türünün işleneni ile T karşılaştırılır null ve çalışma zamanı türü T bir değer türü ise, karşılaştırma sonucu olur false .If an operand of a type parameter type T is compared to null, and the run-time type of T is a value type, the result of the comparison is false.

Aşağıdaki örnek, kısıtlanmamış bir tür parametre türünün bağımsız değişkeninin olup olmadığını denetler null .The following example checks whether an argument of an unconstrained type parameter type is null.

class C<T>
{
    void F(T x) {
        if (x == null) throw new ArgumentNullException();
        ...
    }
}

x == nullYapı, T bir değer türünü temsil etse de izin verilir ve sonuç yalnızca false T bir değer türü olduğu zaman olarak tanımlanır.The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type.

Formun bir işlemi veya varsa, x == y x != y operator == operator != işleç aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözünürlüğü) kuralları, önceden tanımlanmış başvuru türü eşitlik işleci yerine bu işleci seçer.For an operation of the form x == y or x != y, if any applicable operator == or operator != exists, the operator overload resolution (Binary operator overload resolution) rules will select that operator instead of the predefined reference type equality operator. Ancak, her zaman önceden tanımlanmış başvuru türü eşitlik işlecini seçerek, işlenenleri bir veya her ikisini de türüne açıkça atayarak seçebilirsiniz object .However, it is always possible to select the predefined reference type equality operator by explicitly casting one or both of the operands to type object. ÖrnekteThe example

using System;

class Test
{
    static void Main() {
        string s = "Test";
        string t = string.Copy(s);
        Console.WriteLine(s == t);
        Console.WriteLine((object)s == t);
        Console.WriteLine(s == (object)t);
        Console.WriteLine((object)s == (object)t);
    }
}

çıktıyı üretirproduces the output

True
False
False
False

sVe t değişkenleri string aynı karakterleri içeren iki ayrı örneğe başvurur.The s and t variables refer to two distinct string instances containing the same characters. TrueHer iki işlenen de türü olduğunda, önceden tanımlanmış dize eşitlik işleci (dize eşitlik işleçleri) seçildiğinden ilk karşılaştırma çıkışları string .The first comparison outputs True because the predefined string equality operator (String equality operators) is selected when both operands are of type string. Falseİşlenenleri bir veya her ikisi de tür olduğunda, önceden tanımlanmış başvuru türü eşitlik işleci seçildiğinden, kalan tüm çıktılar karşılaştırılmasını kullanır object .The remaining comparisons all output False because the predefined reference type equality operator is selected when one or both of the operands are of type object.

Yukarıdaki tekniğinin değer türleri için anlamlı olmadığına unutmayın.Note that the above technique is not meaningful for value types. ÖrnekteThe example

class Test
{
    static void Main() {
        int i = 123;
        int j = 123;
        System.Console.WriteLine((object)i == (object)j);
    }
}

yayınlar False , kutuların iki ayrı paketlenmiş değer örneğine başvuru oluşturduğundan verir int .outputs False because the casts create references to two separate instances of boxed int values.

Dize eşitlik işleçleriString equality operators

Önceden tanımlanmış dize eşitlik işleçleri şunlardır:The predefined string equality operators are:

bool operator ==(string x, string y);
bool operator !=(string x, string y);

stringAşağıdakilerden biri doğru olduğunda iki değer eşit kabul edilir:Two string values are considered equal when one of the following is true:

  • Her iki değer de null .Both values are null.
  • Her iki değer de aynı uzunlukta ve her bir karakter konumunda özdeş karakterlere sahip olan dize örneklerine yönelik null olmayan başvurulardır.Both values are non-null references to string instances that have identical lengths and identical characters in each character position.

Dize eşitlik işleçleri dize başvuruları yerine dize değerlerini karşılaştırır.The string equality operators compare string values rather than string references. İki ayrı dize örneği tam olarak aynı karakter dizisini içerdiğinde, dizelerin değerleri eşittir, ancak başvurular farklıdır.When two separate string instances contain the exact same sequence of characters, the values of the strings are equal, but the references are different. Başvuru türü eşitlik işleçleribölümünde açıklandığı gibi, dize değerleri yerine dize başvurularını karşılaştırmak için başvuru türü eşitlik işleçleri kullanılabilir.As described in Reference type equality operators, the reference type equality operators can be used to compare string references instead of string values.

Eşitlik işleçlerini devretmekDelegate equality operators

Her temsilci türü örtük olarak aşağıdaki önceden tanımlı karşılaştırma işleçlerini sağlar:Every delegate type implicitly provides the following predefined comparison operators:

bool operator ==(System.Delegate x, System.Delegate y);
bool operator !=(System.Delegate x, System.Delegate y);

İki temsilci örneği aşağıdaki gibi kabul edilir:Two delegate instances are considered equal as follows:

  • Temsilci örneklerinden biri ise, null yalnızca ve her ikisi de varsa eşittir null .If either of the delegate instances is null, they are equal if and only if both are null.
  • Temsilcilerin farklı çalışma zamanı türleri varsa, bunlar hiçbir zaman eşit değildir.If the delegates have different run-time type they are never equal.
  • Her iki temsilci örneği de bir çağırma listesine (temsilci bildirimleri) sahip ise, bu örnekler eşit olur ve yalnızca çağırma listeleri aynı uzunluktadır ve tek bir çağrı listesindeki her giriş, karşılık gelen giriş listesindeki diğer çağrı listesinde sırasıyla eşittir (aşağıda tanımlandığı gibi).If both of the delegate instances have an invocation list (Delegate declarations), those instances are equal if and only if their invocation lists are the same length, and each entry in one's invocation list is equal (as defined below) to the corresponding entry, in order, in the other's invocation list.

Aşağıdaki kurallar, çağırma listesi girişlerinin eşitlik düzeyini yönetir:The following rules govern the equality of invocation list entries:

  • İki çağırma listesi girişi her ikisi de aynı statik yönteme başvurursanız, girdiler eşittir.If two invocation list entries both refer to the same static method then the entries are equal.
  • İki çağırma listesi girişi her ikisi de aynı hedef nesnede statik olmayan bir yönteme (başvuru eşitlik işleçleri tarafından tanımlandığı gibi) başvurmazsa, girdiler eşittir.If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
  • Aynı (muhtemelen boş) yakalanan dış değişken örnekleri kümesiyle aynı (büyük olasılıkla boş) bir değere sahip anlamsal özdeş anonymous_method_expression s veya lambda_expression s değerlendirmesinden üretilen çağırma listesi girişleri, eşit olması için izin verilir (ancak gerekli değildir).Invocation list entries produced from evaluation of semantically identical anonymous_method_expression s or lambda_expression s with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.

Eşitlik işleçleri ve nullEquality operators and null

==Ve != işleçleri, null işlem için önceden tanımlanmış veya Kullanıcı tanımlı işleç (unlifted veya yükseltilmemiş biçiminde) mevcut olmasa bile, tek bir işlenenin null yapılabilir türde ve diğeri de değişmez değer olarak izin verir.The == and != operators permit one operand to be a value of a nullable type and the other to be the null literal, even if no predefined or user-defined operator (in unlifted or lifted form) exists for the operation.

Formlardan birine bir işlem içinFor an operation of one of the forms

x == null
null == x
x != null
null != x

x, işleç aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümlemesi) uygun bir işleç bulamazsa, bunun yerine öğesinin özelliğinden hesaplanamazsa, null yapılabilir bir türün bir ifadesidir HasValue x .where x is an expression of a nullable type, if operator overload resolution (Binary operator overload resolution) fails to find an applicable operator, the result is instead computed from the HasValue property of x. Özellikle, ilk iki form öğesine çevrilir !x.HasValue ve son iki form öğesine çevrilir x.HasValue .Specifically, the first two forms are translated into !x.HasValue, and last two forms are translated into x.HasValue.

SIS işleciThe is operator

isİşleci, bir nesnenin çalışma zamanı türünün belirli bir tür ile uyumlu olup olmadığını dinamik olarak denetlemek için kullanılır.The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. İşlemin sonucu E is T olarak, E bir ifadedir ve T bir tür ise, bir E T başvuru dönüştürmesi, paketleme dönüştürmesi veya bir kutudan çıkarma dönüştürmesi tarafından türe başarıyla dönüştürülüp dönüştürülmeyeceğini belirten bir Boole değeridir.The result of the operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. Tür bağımsız değişkenleri tüm tür parametreleri yerine eklendikten sonra işlem aşağıdaki gibi değerlendirilir:The operation is evaluated as follows, after type arguments have been substituted for all type parameters:

  • EAnonim bir işlevse, derleme zamanı hatası oluşurIf E is an anonymous function, a compile-time error occurs
  • Eğer E null türü bir başvuru türü veya null yapılabilir bir tür ise ve değeri null ise, bir yöntem grubu veya değişmez değer ise, E E sonuç false olur.If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.
  • Aksi takdirde, D aşağıdaki şekilde dinamik türünü temsil edelim E :Otherwise, let D represent the dynamic type of E as follows:
    • Türü E bir başvuru türü ise, D örnek başvurusunun çalışma zamanı türüdür E .If the type of E is a reference type, D is the run-time type of the instance reference by E.
    • Türü E null yapılabilir bir tür ise, D Bu null yapılabilir türün temel türüdür.If the type of E is a nullable type, D is the underlying type of that nullable type.
    • Türü E null yapılamayan bir değer türü ise, D türüdür E .If the type of E is a non-nullable value type, D is the type of E.
  • İşlemin sonucu D T aşağıdaki gibi değişir:The result of the operation depends on D and T as follows:
    • TBir başvuru türü ise, sonuç true olur D ve T aynı türde ise, D bir başvuru türüdür ve öğesinden bir örtük başvuru dönüştürmesi varsa D ya da T D bir değer türüdür ve ' dan bir kutulama dönüştürmesi olur D T .If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
    • TNull yapılabilir bir tür ise, temel türü ise sonuç true olur D T .If T is a nullable type, the result is true if D is the underlying type of T.
    • TNull yapılamayan bir değer türü ise sonuç, D ve aynı türde ise true olur T .If T is a non-nullable value type, the result is true if D and T are the same type.
    • Aksi takdirde, sonuç false 'tur.Otherwise, the result is false.

Kullanıcı tanımlı dönüştürmelerin işleç tarafından değerlendirilmediğini unutmayın is .Note that user defined conversions, are not considered by the is operator.

As işleciThe as operator

asİşleci, bir değeri açıkça belirli bir başvuru türüne veya null yapılabilir türe dönüştürmek için kullanılır.The as operator is used to explicitly convert a value to a given reference type or nullable type. Atama ifadesinin (cast ifadeleri) aksine, as işleç hiçbir şekilde özel durum oluşturmaz.Unlike a cast expression (Cast expressions), the as operator never throws an exception. Bunun yerine, belirtilen dönüştürme mümkün değilse, sonuçta elde edilen değer olur null .Instead, if the indicated conversion is not possible, the resulting value is null.

Formun bir işleminde E as T , E bir ifade olmalıdır ve bir T başvuru türü, başvuru türü olarak bilinen bir tür parametresi veya null yapılabilir bir tür olmalıdır.In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. Ayrıca, aşağıdakilerden en az birinin doğru olması gerekir, aksi takdirde bir derleme zamanı hatası oluşur:Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:

Derleme zamanı türü E değilse dynamic , işlem E as T aynı sonucu şu şekilde üretirIf the compile-time type of E is not dynamic, the operation E as T produces the same result as

E is T ? (T)(E) : (T)null

hariç E yalnızca bir kez değerlendirilir.except that E is only evaluated once. Derleyicinin, E as T Yukarıdaki genişletme tarafından kapsanan iki dinamik tür denetimi yerine en çok bir dinamik tür denetimi gerçekleştirmesi için en iyi hale getirmesi beklenmelidir.The compiler can be expected to optimize E as T to perform at most one dynamic type check as opposed to the two dynamic type checks implied by the expansion above.

Derleme zamanı türü E ise dynamic , atama işlecinin aksine as işleç dinamik olarak bağlı değildir (dinamik bağlama).If the compile-time type of E is dynamic, unlike the cast operator the as operator is not dynamically bound (Dynamic binding). Bu nedenle, bu durumda genişletme şu şekilde olur:Therefore the expansion in this case is:

E is T ? (T)(object)(E) : (T)null

Kullanıcı tanımlı dönüştürmeler gibi bazı dönüştürmelerde as işleçle mümkün olmadığı ve bunun yerine atama ifadeleri kullanılarak gerçekleştirilmesi gerektiğini unutmayın.Note that some conversions, such as user defined conversions, are not possible with the as operator and should instead be performed using cast expressions.

ÖrnekteIn the example

class X
{

    public string F(object o) {
        return o as string;        // OK, string is a reference type
    }

    public T G<T>(object o) where T: Attribute {
        return o as T;             // Ok, T has a class constraint
    }

    public U H<U>(object o) {
        return o as U;             // Error, U is unconstrained 
    }
}

öğesinin tür parametresi T , G sınıf kısıtlaması içerdiğinden, başvuru türü olarak bilinir.the type parameter T of G is known to be a reference type, because it has the class constraint. U' In tür parametresi H değildir; bu nedenle as işlecinin ' de kullanılmasına H izin verilmez.The type parameter U of H is not however; hence the use of the as operator in H is disallowed.

Mantıksal işleçlerLogical operators

&, ^ Ve | işleçleri mantıksal işleçler olarak adlandırılır.The &, ^, and | operators are called the logical operators.

and_expression
    : equality_expression
    | and_expression '&' equality_expression
    ;

exclusive_or_expression
    : and_expression
    | exclusive_or_expression '^' and_expression
    ;

inclusive_or_expression
    : exclusive_or_expression
    | inclusive_or_expression '|' exclusive_or_expression
    ;

Bir mantıksal işlecin işleneni derleme zamanı türüne sahipse dynamic , ifade dinamik olarak bağlanır (dinamik bağlama).If an operand of a logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). Bu durumda, ifadenin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, derleme zamanı türüne sahip olan işlenenleri çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir dynamic .In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

Formun bir işlemi, x op y op mantıksal işleçlerden biri olduğunda, belirli bir operatör uygulamasını seçmek için aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümlemesi) uygulanır.For an operation of the form x op y, where op is one of the logical operators, overload resolution (Binary operator overload resolution) is applied to select a specific operator implementation. İşlenenler, seçili işlecin parametre türlerine dönüştürülür ve sonucun türü işlecin dönüş türüdür.The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Önceden tanımlanmış mantıksal işleçler aşağıdaki bölümlerde açıklanmıştır.The predefined logical operators are described in the following sections.

Tamsayı mantıksal işleçleriInteger logical operators

Önceden tanımlı tamsayı mantıksal işleçleri şunlardır:The predefined integer logical operators are:

int operator &(int x, int y);
uint operator &(uint x, uint y);
long operator &(long x, long y);
ulong operator &(ulong x, ulong y);

int operator |(int x, int y);
uint operator |(uint x, uint y);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);

int operator ^(int x, int y);
uint operator ^(uint x, uint y);
long operator ^(long x, long y);
ulong operator ^(ulong x, ulong y);

&İşleci iki işlenenin bit düzeyinde mantıksal AND öğesini hesaplar, | işleç iki işlenenin bit düzeyinde mantıksal öğesini hesaplar OR ve ^ işleç iki işlenenin bit düzeyinde mantıksal dışlamalı bir mantıksal değeri hesaplar OR .The & operator computes the bitwise logical AND of the two operands, the | operator computes the bitwise logical OR of the two operands, and the ^ operator computes the bitwise logical exclusive OR of the two operands. Bu işlemlerden taşmalar mümkün değildir.No overflows are possible from these operations.

Sabit listesi mantıksal işleçleriEnumeration logical operators

Her numaralandırma türü E örtük olarak aşağıdaki önceden tanımlanmış mantıksal işleçleri sağlar:Every enumeration type E implicitly provides the following predefined logical operators:

E operator &(E x, E y);
E operator |(E x, E y);
E operator ^(E x, E y);

Değerlendirme sonucu x op y , x ve y temel alınan bir tür numaralandırma türünün ifadeleri, E U ve op mantıksal işleçlerden biridir, tam olarak değerlendirmesiyle aynıdır (E)((U)x op (U)y) .The result of evaluating x op y, where x and y are expressions of an enumeration type E with an underlying type U, and op is one of the logical operators, is exactly the same as evaluating (E)((U)x op (U)y). Diğer bir deyişle, mantıksal işleçler numaralandırma türü mantıksal işlemleri yalnızca iki işlenenin temel alınan türünde gerçekleştirir.In other words, the enumeration type logical operators simply perform the logical operation on the underlying type of the two operands.

Boole mantıksal işleçleriBoolean logical operators

Önceden tanımlanmış Boole mantıksal işleçleri şunlardır:The predefined boolean logical operators are:

bool operator &(bool x, bool y);
bool operator |(bool x, bool y);
bool operator ^(bool x, bool y);

, Ve öğelerinin sonucu x & y olur true x y true .The result of x & y is true if both x and y are true. Aksi takdirde, sonuç olur false .Otherwise, the result is false.

x | yYa da ise sonucu true x y true .The result of x | y is true if either x or y is true. Aksi takdirde, sonuç olur false .Otherwise, the result is false.

Öğesinin sonucu, x ^ y true ve ise x true y false , ve ' dir x false y true .The result of x ^ y is true if x is true and y is false, or x is false and y is true. Aksi takdirde, sonuç olur false .Otherwise, the result is false. İşlenenler tür olduğunda bool ^ işleç, işleçle aynı sonucu hesaplar != .When the operands are of type bool, the ^ operator computes the same result as the != operator.

Null yapılabilir Boolean mantıksal işleçlerNullable boolean logical operators

Nullable Boolean türü bool? üç değeri temsil edebilir,, true false ve null , ve kavramsal olarak SQL 'deki Boole ifadeleri için kullanılan üç değerli türe benzer.The nullable boolean type bool? can represent three values, true, false, and null, and is conceptually similar to the three-valued type used for boolean expressions in SQL. &İşlenenleri için ve işleçleri tarafından üretilen SONUÇLARıN | bool? SQL 'in üç değerli mantığı ile tutarlı olduğundan emin olmak için, aşağıdaki önceden tanımlanmış işleçler verilmiştir:To ensure that the results produced by the & and | operators for bool? operands are consistent with SQL's three-valued logic, the following predefined operators are provided:

bool? operator &(bool? x, bool? y);
bool? operator |(bool? x, bool? y);

Aşağıdaki tabloda, ve değerlerinin tüm birleşimleri için bu işleçler tarafından oluşturulan sonuçlar listelenmektedir true false null .The following table lists the results produced by these operators for all combinations of the values true, false, and null.

x y x & y x | y
true true true true
true false false true
true null null true
false true false true
false false false false
false null false null
null true null true
null false false null
null null null null

Koşullu mantıksal işleçlerConditional logical operators

&& ve || işleçleri koşullu mantıksal işleçler olarak adlandırılır.The && and || operators are called the conditional logical operators. Bunlar ayrıca "kısa devre dışı" mantıksal işleçler olarak da adlandırılır.They are also called the "short-circuiting" logical operators.

conditional_and_expression
    : inclusive_or_expression
    | conditional_and_expression '&&' inclusive_or_expression
    ;

conditional_or_expression
    : conditional_and_expression
    | conditional_or_expression '||' conditional_and_expression
    ;

&&Ve || işleçleri, & ve işleçlerinin koşullu sürümleridir | :The && and || operators are conditional versions of the & and | operators:

  • İşlem, x && y işleme karşılık gelir x & y , y ancak yalnızca değilse değerlendirilir x false .The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is not false.
  • İşlem, x || y işleme karşılık gelir x | y , y ancak yalnızca değilse değerlendirilir x true .The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.

Koşullu bir mantıksal işlecin işleneni derleme zamanı türüne sahipse dynamic , ifade dinamik olarak bağlanır (dinamik bağlama).If an operand of a conditional logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). Bu durumda, ifadenin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm, derleme zamanı türüne sahip olan işlenenleri çalışma zamanı türü kullanılarak çalışma zamanında gerçekleşmeyecektir dynamic .In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

x && yYa da x || y işlem yazılmış gibi aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümü) uygulanarak işlenir x & y x | y .An operation of the form x && y or x || y is processed by applying overload resolution (Binary operator overload resolution) as if the operation was written x & y or x | y. NiThen,

Koşullu mantıksal işleçleri doğrudan aşırı yüklemek mümkün değildir.It is not possible to directly overload the conditional logical operators. Ancak, Koşullu mantıksal işleçler normal mantıksal işleçler açısından değerlendirildiğinden, normal mantıksal operatörlerin aşırı yüklemeleri, Koşullu mantıksal işleçlerin aşırı yüklerini de kabul edilen belirli kısıtlamalarla birlikte bulunur.However, because the conditional logical operators are evaluated in terms of the regular logical operators, overloads of the regular logical operators are, with certain restrictions, also considered overloads of the conditional logical operators. Bu, Kullanıcı tanımlı Koşullu mantıksal işleçlerdedaha ayrıntılı olarak açıklanmıştır.This is described further in User-defined conditional logical operators.

Boole Koşullu mantıksal işleçlerBoolean conditional logical operators

Veya türü işlenenler veya && || bool işlenenleri geçerli bir veya olmayan türlerindiğinde, operator & operator | ancak örtük dönüştürmeler tanımlamak için, bool işlem şu şekilde işlenir:When the operands of && or || are of type bool, or when the operands are of types that do not define an applicable operator & or operator |, but do define implicit conversions to bool, the operation is processed as follows:

  • İşlem x && y olarak değerlendirilir x ? y : false .The operation x && y is evaluated as x ? y : false. Diğer bir deyişle, x ilk olarak değerlendirilir ve türüne dönüştürülür bool .In other words, x is first evaluated and converted to type bool. Eğer ise, x true y değerlendirilir ve türüne dönüştürülür bool ve bu işlemin sonucu olur.Then, if x is true, y is evaluated and converted to type bool, and this becomes the result of the operation. Aksi takdirde, işlemin sonucu false .Otherwise, the result of the operation is false.
  • İşlem x || y olarak değerlendirilir x ? true : y .The operation x || y is evaluated as x ? true : y. Diğer bir deyişle, x ilk olarak değerlendirilir ve türüne dönüştürülür bool .In other words, x is first evaluated and converted to type bool. Eğer, x ise, true işlemin sonucu olur true .Then, if x is true, the result of the operation is true. Aksi takdirde, y değerlendirilir ve türüne dönüştürülür bool ve bu işlemin sonucu olur.Otherwise, y is evaluated and converted to type bool, and this becomes the result of the operation.

Kullanıcı tanımlı Koşullu mantıksal işleçlerUser-defined conditional logical operators

Ya da, && || geçerli bir Kullanıcı tanımlı veya ' ı belirten türlerin işlenenleri olduğunda, operator & operator | aşağıdakilerin her ikisi de doğru olmalıdır; burada, T Seçili işlecin bildirildiği türdür:When the operands of && or || are of types that declare an applicable user-defined operator & or operator |, both of the following must be true, where T is the type in which the selected operator is declared:

  • Seçili işlecin her bir parametresinin dönüş türü ve türü olmalıdır T .The return type and the type of each parameter of the selected operator must be T. Diğer bir deyişle işleç, AND türünde iki işlenenin mantıksal veya mantıksal öğesini hesaplamalıdır OR T ve türünde bir sonuç döndürmelidir T .In other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T.
  • T , ve bildirimlerini içermelidir operator true operator false .T must contain declarations of operator true and operator false.

Bu gereksinimlerin herhangi biri karşılanmıyorsa bağlama zamanı hatası oluşur.A binding-time error occurs if either of these requirements is not satisfied. Aksi takdirde, && veya || işlemi kullanıcı tanımlı operator true veya operator false Seçili kullanıcı tanımlı işleçle birleştirilerek değerlendirilir:Otherwise, the && or || operation is evaluated by combining the user-defined operator true or operator false with the selected user-defined operator:

  • İşlem x && y olarak değerlendirilir T.false(x) ? x : T.&(x, y) , burada ' T.false(x) de bildirildiği bir çağrıdır operator false T ve T.&(x, y) Seçili bir çağrıdır operator & .The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. Diğer bir deyişle, x ilk olarak değerlendirilir ve operator false sonuçta kesinlikle yanlış olduğunu tespit etmek için çağrılır x .In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Daha sonra, x kesinlikle yanlış ise, işlemin sonucu daha önce için hesaplanmış değerdir x .Then, if x is definitely false, the result of the operation is the value previously computed for x. Aksi takdirde, y değerlendirilir ve seçilen, operator & daha önce hesaplanan değerde x ve y işlemin sonucunu üretmek için hesaplanan değer üzerinde çağrılır.Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
  • İşlem x || y olarak değerlendirilir T.true(x) ? x : T.|(x, y) , burada ' T.true(x) de bildirildiği bir çağrıdır operator true T ve T.|(x,y) Seçili bir çağrıdır operator| .The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x,y) is an invocation of the selected operator|. Diğer bir deyişle, x ilk olarak değerlendirilir ve operator true kesin olarak doğru olup olmadığını belirlemesi için sonuç üzerinde çağrılır x .In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. Daha sonra x kesin doğru ise, işlemin sonucu daha önce için hesaplanmış değerdir x .Then, if x is definitely true, the result of the operation is the value previously computed for x. Aksi takdirde, y değerlendirilir ve seçilen, operator | daha önce hesaplanan değerde x ve y işlemin sonucunu üretmek için hesaplanan değer üzerinde çağrılır.Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.

Bu işlemlerden birinde, tarafından verilen ifade x yalnızca bir kez değerlendirilir ve tarafından verilen ifade, y tam olarak bir kez değerlendirilmez veya değerlendirilmez.In either of these operations, the expression given by x is only evaluated once, and the expression given by y is either not evaluated or evaluated exactly once.

Ve uygulayan bir tür örneği için operator true operator false bkz. veritabanı Boole türü.For an example of a type that implements operator true and operator false, see Database boolean type.

Null birleştirme işleciThe null coalescing operator

??İşlecine null birleşim işleci denir.The ?? operator is called the null coalescing operator.

null_coalescing_expression
    : conditional_or_expression
    | conditional_or_expression '??' null_coalescing_expression
    ;

Formun null birleşim ifadesi null a ?? b a yapılabilir bir tür veya başvuru türünde olmalıdır.A null coalescing expression of the form a ?? b requires a to be of a nullable type or reference type. aNull olmayan ise, sonucu olur a ?? b a ; Aksi takdirde sonuç olur b .If a is non-null, the result of a ?? b is a; otherwise, the result is b. İşlem b yalnızca null ise değerlendirilir a .The operation evaluates b only if a is null.

Null birleştirme işleci, işlemlerin sağdan sola gruplanarak doğru ilişkilendirilebilir.The null coalescing operator is right-associative, meaning that operations are grouped from right to left. Örneğin, formun bir ifadesi a ?? b ?? c olarak değerlendirilir a ?? (b ?? c) .For example, an expression of the form a ?? b ?? c is evaluated as a ?? (b ?? c). Genel koşullarda, formun bir ifadesi E1 ?? E2 ?? ... ?? En null olmayan veya tüm işlenenler null ise null olan işlenenlerin Birincini döndürür.In general terms, an expression of the form E1 ?? E2 ?? ... ?? En returns the first of the operands that is non-null, or null if all operands are null.

İfadenin türü, a ?? b işlenenlerde hangi örtük dönüştürmelerin kullanılabilir olduğuna bağlıdır.The type of the expression a ?? b depends on which implicit conversions are available on the operands. Tercih sırasına göre,, a ?? b , veya türü ' A0 dir A B A a ( a bir türüne sahip olan), B türüdür b ( b bir türü olan), ve A0 öğesinin temel alınan türü A A null yapılabilir bir tür ise veya A Aksi durumda.In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. Özellikle, a ?? b Şu şekilde işlenir:Specifically, a ?? b is processed as follows:

  • Varsa A ve null yapılabilir bir tür ya da bir başvuru türü değilse, derleme zamanı hatası oluşur.If A exists and is not a nullable type or a reference type, a compile-time error occurs.
  • bDinamik bir ifadesiyse sonuç türü olur dynamic .If b is a dynamic expression, the result type is dynamic. Çalışma zamanında a ilk olarak değerlendirilir.At run-time, a is first evaluated. aNull değilse, a dinamik olarak dönüştürülür ve bu sonuç olur.If a is not null, a is converted to dynamic, and this becomes the result. Aksi takdirde, b değerlendirilir ve bu sonuç olur.Otherwise, b is evaluated, and this becomes the result.
  • Aksi takdirde, A varsa ve null yapılabilir bir tür ise ve öğesinden örtük bir dönüştürme b varsa A0 , sonuç türü olur A0 .Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. Çalışma zamanında a ilk olarak değerlendirilir.At run-time, a is first evaluated. aNull değilse, a türüne sarmalanmış değildir A0 ve bu sonuç olur.If a is not null, a is unwrapped to type A0, and this becomes the result. Aksi takdirde, b değerlendirilir ve türüne dönüştürülür A0 ve bu sonuç olur.Otherwise, b is evaluated and converted to type A0, and this becomes the result.
  • Aksi halde, varsa A ve öğesinden örtük bir dönüştürme varsa b A , sonuç türü olur A .Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. Çalışma zamanında a ilk olarak değerlendirilir.At run-time, a is first evaluated. aNull değilse a sonuç olur.If a is not null, a becomes the result. Aksi takdirde, b değerlendirilir ve türüne dönüştürülür A ve bu sonuç olur.Otherwise, b is evaluated and converted to type A, and this becomes the result.
  • Aksi halde, b bir türü B ve öğesinden örtük bir dönüştürme varsa a B , sonuç türü olur B .Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. Çalışma zamanında a ilk olarak değerlendirilir.At run-time, a is first evaluated. aNull değilse, a Type A0 ( A varsa ve null yapılabilir) ve türe dönüştürülürse, B Bu sonuç olur.If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Aksi takdirde, b değerlendirilir ve sonuç olur.Otherwise, b is evaluated and becomes the result.
  • Aksi halde a , b uyumsuzdur ve bir derleme zamanı hatası oluşur.Otherwise, a and b are incompatible, and a compile-time error occurs.

Koşullu işleçConditional operator

?:İşleci koşullu işleç olarak adlandırılır.The ?: operator is called the conditional operator. Üçlü işleç olarak da adlandırılır.It is at times also called the ternary operator.

conditional_expression
    : null_coalescing_expression
    | null_coalescing_expression '?' expression ':' expression
    ;

Formun koşullu bir ifadesi ilk olarak b ? x : y koşulu değerlendirir b .A conditional expression of the form b ? x : y first evaluates the condition b. , İse, b true x değerlendirilir ve işlemin sonucu olur.Then, if b is true, x is evaluated and becomes the result of the operation. Aksi takdirde, y değerlendirilir ve işlemin sonucu olur.Otherwise, y is evaluated and becomes the result of the operation. Koşullu bir ifade hiçbir şekilde hem hem de değerlendirmez x y .A conditional expression never evaluates both x and y.

Koşullu operatör doğru ilişkilendirilebilir, yani işlemler sağdan sola gruplandırılır.The conditional operator is right-associative, meaning that operations are grouped from right to left. Örneğin, formun bir ifadesi a ? b : c ? d : e olarak değerlendirilir a ? b : (c ? d : e) .For example, an expression of the form a ? b : c ? d : e is evaluated as a ? b : (c ? d : e).

İşlecin ilk işleneni örtük olarak ?: dönüştürülebilen bir ifade bool veya uygulayan bir türün bir ifadesi olmalıdır operator true .The first operand of the ?: operator must be an expression that can be implicitly converted to bool, or an expression of a type that implements operator true. Bu gereksinimlerin hiçbiri karşılanmazsa, bir derleme zamanı hatası oluşur.If neither of these requirements is satisfied, a compile-time error occurs.

İkinci ve üçüncü işlenen x ve işleci, y ?: koşullu ifadenin türünü denetler.The second and third operands, x and y, of the ?: operator control the type of the conditional expression.

  • Eğer x türüne sahipse X ve y türüne sahipse YIf x has type X and y has type Y then
    • Örtük dönüştürme (örtük dönüştürmeler) öğesinden öğesine X Y , ancak öğesinden öğesine yoksa, Y X Y koşullu ifadenin türüdür.If an implicit conversion (Implicit conversions) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
    • Örtük dönüştürme (örtük dönüştürmeler) öğesinden öğesine Y X , ancak öğesinden öğesine yoksa, X Y X koşullu ifadenin türüdür.If an implicit conversion (Implicit conversions) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
    • Aksi takdirde, hiçbir ifade türü belirlenemez ve derleme zamanı hatası oluşur.Otherwise, no expression type can be determined, and a compile-time error occurs.
  • Yalnızca biri x ve y türünde bir tür varsa ve her ikisi de x ve, her ikisi de y Bu türe örtülü olarak dönüştürülesiyse, bu, koşullu ifadenin türüdür.If only one of x and y has a type, and both x and y, of are implicitly convertible to that type, then that is the type of the conditional expression.
  • Aksi takdirde, hiçbir ifade türü belirlenemez ve derleme zamanı hatası oluşur.Otherwise, no expression type can be determined, and a compile-time error occurs.

Formun koşullu ifadesinin çalışma zamanı işleme b ? x : y aşağıdaki adımlardan oluşur:The run-time processing of a conditional expression of the form b ? x : y consists of the following steps:

  • Birincisi, b değerlendirilir ve bool değeri b belirlenir:First, b is evaluated, and the bool value of b is determined:
    • Türünden örtük bir dönüştürme varsa b bool , bu örtük dönüştürme bir değer üretmek için gerçekleştirilir bool .If an implicit conversion from the type of b to bool exists, then this implicit conversion is performed to produce a bool value.
    • Aksi takdirde, operator true türü tarafından tanımlanan b bir değer üretmek için çağrılır bool .Otherwise, the operator true defined by the type of b is invoked to produce a bool value.
  • boolYukarıdaki adım tarafından üretilen değer ise, true x değerlendirilir ve koşullu ifadenin türüne dönüştürülür ve bu, koşullu ifadenin sonucu olur.If the bool value produced by the step above is true, then x is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.
  • Aksi takdirde, y değerlendirilir ve koşullu ifadenin türüne dönüştürülür ve bu, koşullu ifadenin sonucu olur.Otherwise, y is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.

Anonim işlev ifadeleriAnonymous function expressions

Anonim işlev , "satır içi" yöntem tanımını temsil eden bir ifadedir.An anonymous function is an expression that represents an "in-line" method definition. Anonim bir işlev, ve için bir değer veya tür içermez, ancak uyumlu bir temsilciye veya ifade ağacı türüne dönüştürülebilir.An anonymous function does not have a value or type in and of itself, but is convertible to a compatible delegate or expression tree type. Anonim işlev dönüştürmenin değerlendirmesi, dönüştürmenin hedef türüne bağlıdır: bir temsilci türü ise, dönüştürme, anonim işlevin tanımladığı yönteme başvuran bir temsilci değeri olarak değerlendirilir.The evaluation of an anonymous function conversion depends on the target type of the conversion: If it is a delegate type, the conversion evaluates to a delegate value referencing the method which the anonymous function defines. Bir ifade ağacı türü ise dönüştürme, yöntemin yapısını bir nesne yapısı olarak temsil eden bir ifade ağacı olarak değerlendirilir.If it is an expression tree type, the conversion evaluates to an expression tree which represents the structure of the method as an object structure.

Geçmiş nedenlerle anonim işlevlerin iki sözdizimsel özelliği vardır, örneğin lambda_expression s ve anonymous_method_expression s.For historical reasons there are two syntactic flavors of anonymous functions, namely lambda_expression s and anonymous_method_expression s. Neredeyse tüm amaçlar için lambda_expression s, geriye doğru uyumluluk için dilde kalan anonymous_method_expression s ' den daha kısa ve açıklayıcı bir şekilde bulunur.For almost all purposes, lambda_expression s are more concise and expressive than anonymous_method_expression s, which remain in the language for backwards compatibility.

lambda_expression
    : anonymous_function_signature '=>' anonymous_function_body
    ;

anonymous_method_expression
    : 'delegate' explicit_anonymous_function_signature? block
    ;

anonymous_function_signature
    : explicit_anonymous_function_signature
    | implicit_anonymous_function_signature
    ;

explicit_anonymous_function_signature
    : '(' explicit_anonymous_function_parameter_list? ')'
    ;

explicit_anonymous_function_parameter_list
    : explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)*
    ;

explicit_anonymous_function_parameter
    : anonymous_function_parameter_modifier? type identifier
    ;

anonymous_function_parameter_modifier
    : 'ref'
    | 'out'
    ;

implicit_anonymous_function_signature
    : '(' implicit_anonymous_function_parameter_list? ')'
    | implicit_anonymous_function_parameter
    ;

implicit_anonymous_function_parameter_list
    : implicit_anonymous_function_parameter (',' implicit_anonymous_function_parameter)*
    ;

implicit_anonymous_function_parameter
    : identifier
    ;

anonymous_function_body
    : expression
    | block
    ;

=>İşleci atama () ile aynı önceliğe sahiptir = ve doğru ilişkilendirilebilir.The => operator has the same precedence as assignment (=) and is right-associative.

Değiştiriciye sahip anonim bir işlev async zaman uyumsuz bir işlevdir ve zaman uyumsuz işlevlerdeaçıklanan kuralları izler.An anonymous function with the async modifier is an async function and follows the rules described in Async functions.

Bir lambda_expression biçimindeki anonim işlevin parametreleri açık veya örtük olarak yazılabilir olabilir.The parameters of an anonymous function in the form of a lambda_expression can be explicitly or implicitly typed. Açıkça yazılmış bir parametre listesinde, her parametrenin türü açıkça belirtilir.In an explicitly typed parameter list, the type of each parameter is explicitly stated. Örtük olarak yazılmış bir parametre listesinde, parametrelerin türleri, anonim işlevin gerçekleştiği bağlamdan çıkarslanmıştır — özellikle, anonim işlev uyumlu bir temsilci türüne veya ifade ağacı türüne dönüştürüldüğünde, bu tür parametre türlerini (anonim işlev dönüştürmeleri) sağlar.In an implicitly typed parameter list, the types of the parameters are inferred from the context in which the anonymous function occurs—specifically, when the anonymous function is converted to a compatible delegate type or expression tree type, that type provides the parameter types (Anonymous function conversions).

Tek ve örtük olarak yazılmış bir parametreye sahip anonim bir işlevde, parantez parametre listesinden atlanabilir.In an anonymous function with a single, implicitly typed parameter, the parentheses may be omitted from the parameter list. Diğer bir deyişle, formun anonim bir işleviIn other words, an anonymous function of the form

( param ) => expr

kısaltılabilircan be abbreviated to

param => expr

Bir anonymous_method_expression biçimindeki adsız işlevin parametre listesi isteğe bağlıdır.The parameter list of an anonymous function in the form of an anonymous_method_expression is optional. Belirtilmişse, parametrelerin açıkça yazılması gerekir.If given, the parameters must be explicitly typed. Aksi takdirde, anonim işlev parametre içermeyen bir temsilciye dönüştürülebilir out .If not, the anonymous function is convertible to a delegate with any parameter list not containing out parameters.

Adsız bir işlevin blok gövdesine erişilebilir (bitiş noktaları ve erişilebilirlik). Bu, anonim işlev ulaşılamaz bir bildirimde gerçekleşmezse.A block body of an anonymous function is reachable (End points and reachability) unless the anonymous function occurs inside an unreachable statement.

Anonim işlevlere bazı örnekler aşağıda verilmiştir:Some examples of anonymous functions follow below:

x => x + 1                              // Implicitly typed, expression body
x => { return x + 1; }                  // Implicitly typed, statement body
(int x) => x + 1                        // Explicitly typed, expression body
(int x) => { return x + 1; }            // Explicitly typed, statement body
(x, y) => x * y                         // Multiple parameters
() => Console.WriteLine()               // No parameters
async (t1,t2) => await t1 + await t2    // Async
delegate (int x) { return x + 1; }      // Anonymous method expression
delegate { return 1 + 1; }              // Parameter list omitted

Lambda_expression s ve anonymous_method_expression s davranışı aşağıdaki noktaları hariç aynıdır:The behavior of lambda_expression s and anonymous_method_expression s is the same except for the following points:

  • anonymous_method_expression s, parametre listesinin tamamen atlanmasına izin verir ve herhangi bir değer parametreleri listesinin temsilci türlerine göz ardı edilir.anonymous_method_expression s permit the parameter list to be omitted entirely, yielding convertibility to delegate types of any list of value parameters.
  • lambda_expression s parametre türlerinin atlanmasına ve çıkarlanmasına izin verirken, anonymous_method_expression s parametre türlerinin açıkça belirtilmesini gerektirir.lambda_expression s permit parameter types to be omitted and inferred whereas anonymous_method_expression s require parameter types to be explicitly stated.
  • Bir lambda_expression gövdesi bir ifade veya deyim bloğu olabilir, ancak bir anonymous_method_expression gövdesi bir deyim bloğu olmalıdır.The body of a lambda_expression can be an expression or a statement block whereas the body of an anonymous_method_expression must be a statement block.
  • Yalnızca lambda_expression s, uyumlu ifade ağacı türlerine Dönüştürmelere sahiptir (ifade ağacı türleri).Only lambda_expression s have conversions to compatible expression tree types (Expression tree types).

Anonim işlev imzalarıAnonymous function signatures

Anonim işlev için isteğe bağlı anonymous_function_signature adları ve isteğe bağlı olarak anonim işlev için biçimsel parametrelerin türlerini tanımlar.The optional anonymous_function_signature of an anonymous function defines the names and optionally the types of the formal parameters for the anonymous function. Anonim işlevin parametrelerinin kapsamı anonymous_function_body.The scope of the parameters of the anonymous function is the anonymous_function_body. (Kapsamlar) Parametre listesi ile birlikte (verildiyse) anonim-yöntem-gövde bir bildirim alanı (Bildirimler) oluşturur.(Scopes) Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space (Declarations). Bu nedenle, anonim işlev parametresinin adı için bir yerel değişkenin adı, yerel sabit veya kapsamı anonymous_method_expression ya da lambda_expression içeren bir parametre için derleme zamanı hatası oluşur.It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the anonymous_method_expression or lambda_expression.

Anonim bir işlevde explicit_anonymous_function_signature varsa, uyumlu temsilci türleri ve ifade ağacı türleri kümesi aynı sırayla aynı parametre türleri ve değiştiricilerle kısıtlıdır.If an anonymous function has an explicit_anonymous_function_signature, then the set of compatible delegate types and expression tree types is restricted to those that have the same parameter types and modifiers in the same order. Yöntem grubu dönüştürmelerinde (Yöntem grubu dönüştürmeleri), anonim işlev parametre türlerinin Contra-varyansı desteklenmez.In contrast to method group conversions (Method group conversions), contra-variance of anonymous function parameter types is not supported. Anonim bir işlevde anonymous_function_signature yoksa, uyumlu temsilci türleri ve ifade ağacı türleri kümesi, parametreleri olmayan olanlarla kısıtlıdır out .If an anonymous function does not have an anonymous_function_signature, then the set of compatible delegate types and expression tree types is restricted to those that have no out parameters.

Anonymous_function_signature öznitelikler veya parametre dizisi içeremediğini unutmayın.Note that an anonymous_function_signature cannot include attributes or a parameter array. Bununla birlikte, bir anonymous_function_signature , parametre listesi parametre dizisi içeren bir temsilci türüyle uyumlu olabilir.Nevertheless, an anonymous_function_signature may be compatible with a delegate type whose parameter list contains a parameter array.

Ayrıca, aynı zamanda derleme zamanında (ifade ağacı türleri) hala başarısız olabilecek bir ifade ağacı türüne dönüştürmeNote also that conversion to an expression tree type, even if compatible, may still fail at compile-time (Expression tree types).

Anonim işlev gövdeleriAnonymous function bodies

Anonim bir işlevin gövdesi (ifadesi veya bloğu) aşağıdaki kurallara tabidir:The body (expression or block) of an anonymous function is subject to the following rules:

  • Anonim işlev bir imza içeriyorsa, İmzada belirtilen parametreler gövdede kullanılabilir.If the anonymous function includes a signature, the parameters specified in the signature are available in the body. Anonim işlevde imza yoksa, parametrelere sahip bir temsilci türüne veya ifade türüne dönüştürülebilir (anonim işlev dönüştürmeleri), ancak parametrelere gövdede erişilemez.If the anonymous function has no signature it can be converted to a delegate type or expression type having parameters (Anonymous function conversions), but the parameters cannot be accessed in the body.
  • ref out En yakın kapsayan anonim işlevin imzasında (varsa) belirtilen veya parametreleri dışında, gövdenin veya parametreye erişmesi için derleme zamanı hatası olur ref out .Except for ref or out parameters specified in the signature (if any) of the nearest enclosing anonymous function, it is a compile-time error for the body to access a ref or out parameter.
  • Türü this bir yapı türü olduğunda, gövdenin erişim için derleme zamanı hatası olur this .When the type of this is a struct type, it is a compile-time error for the body to access this. Bu, erişimin açık (içinde olduğu gibi this.x ) veya örtük olması ( x WHERE, x yapının örnek üyesi olduğu gibi) için geçerlidir.This is true whether the access is explicit (as in this.x) or implicit (as in x where x is an instance member of the struct). Bu kural yalnızca bu erişimi yasaklar ve üye aramanın yapının bir üyesi olup olmadığını etkilemez.This rule simply prohibits such access and does not affect whether member lookup results in a member of the struct.
  • Gövde, anonim işlevin dış değişkenlerine (dış değişkenler) erişebilir.The body has access to the outer variables (Outer variables) of the anonymous function. Bir dış değişkene erişim, lambda_expression veya anonymous_method_expression değerlendirildiği sırada etkin olan değişkenin örneğine başvuracaktır (anonim işlev ifadelerinin değerlendirmesi).Access of an outer variable will reference the instance of the variable that is active at the time the lambda_expression or anonymous_method_expression is evaluated (Evaluation of anonymous function expressions).
  • Gövdesi için bir derleme zamanı hatası, goto break continue hedefi gövdenin dışında veya kapsanan bir anonim işlevin gövdesinde olan bir ifade, ifade veya ifade içeriyor.It is a compile-time error for the body to contain a goto statement, break statement, or continue statement whose target is outside the body or within the body of a contained anonymous function.
  • returnGövdedeki bir ifade, kapsayan işlev üyesinden değil, en yakın kapsayan anonim işlev çağrısından denetim döndürüyor.A return statement in the body returns control from an invocation of the nearest enclosing anonymous function, not from the enclosing function member. Deyimde belirtilen bir ifade, return en yakın kapsayan lambda_expression veya anonymous_method_expression dönüştürüldüğü (anonim işlev dönüştürmeleri), temsilci türünün veya ifade ağacı türünün dönüş türüne örtülü olarak dönüştürülebilir olmalıdır.An expression specified in a return statement must be implicitly convertible to the return type of the delegate type or expression tree type to which the nearest enclosing lambda_expression or anonymous_method_expression is converted (Anonymous function conversions).

Lambda_expression veya anonymous_method_expression için değerlendirme ve çağırma aracılığıyla değil, anonim bir işlevin bloğunu yürütmek için bir yol olup olmadığı açıkça belirtilmemiş.It is explicitly unspecified whether there is any way to execute the block of an anonymous function other than through evaluation and invocation of the lambda_expression or anonymous_method_expression. Özellikle, derleyici bir veya daha fazla adlandırılmış yöntemi ya da türü birleştirerek anonim bir işlev uygulamayı tercih edebilir.In particular, the compiler may choose to implement an anonymous function by synthesizing one or more named methods or types. Bu tür birleştirilmiş öğelerin adları, derleyici kullanımı için ayrılmış bir biçimde olmalıdır.The names of any such synthesized elements must be of a form reserved for compiler use.

Aşırı yükleme çözümlemesi ve anonim işlevlerOverload resolution and anonymous functions

Bir bağımsız değişken listesindeki anonim işlevler tür çıkarımı ve aşırı yükleme çözümüne katılır.Anonymous functions in an argument list participate in type inference and overload resolution. Tam kurallar için lütfen tür çıkarımı ve aşırı yükleme çözümlemesi ' ne bakın.Please refer to Type inference and Overload resolution for the exact rules.

Aşağıdaki örnekte, anonim işlevlerin aşırı yükleme çözünürlüğünde etkileri gösterilmektedir.The following example illustrates the effect of anonymous functions on overload resolution.

class ItemList<T>: List<T>
{
    public int Sum(Func<T,int> selector) {
        int sum = 0;
        foreach (T item in this) sum += selector(item);
        return sum;
    }

    public double Sum(Func<T,double> selector) {
        double sum = 0;
        foreach (T item in this) sum += selector(item);
        return sum;
    }
}

ItemList<T>Sınıfında iki yöntem vardır Sum .The ItemList<T> class has two Sum methods. Her biri bir selector bağımsız değişken alır ve bir liste öğesinden toplanacak değeri ayıklar.Each takes a selector argument, which extracts the value to sum over from a list item. Ayıklanan değer bir int veya bir olabilir double ve elde edilen toplam değer aynı şekilde ya da olur int double .The extracted value can be either an int or a double and the resulting sum is likewise either an int or a double.

SumYöntemler örnek olarak bir sipariş ayrıntı satırı listesinden toplamları hesaplamak için kullanılabilir.The Sum methods could for example be used to compute sums from a list of detail lines in an order.

class Detail
{
    public int UnitCount;
    public double UnitPrice;
    ...
}

void ComputeSums() {
    ItemList<Detail> orderDetails = GetOrderDetails(...);
    int totalUnits = orderDetails.Sum(d => d.UnitCount);
    double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount);
    ...
}

İlk çağrısında orderDetails.Sum , anonim işlev hem hem Sum de ile uyumlu olduğundan her iki yöntem de geçerlidir d => d. UnitCount Func<Detail,int> Func<Detail,double> .In the first invocation of orderDetails.Sum, both Sum methods are applicable because the anonymous function d => d. UnitCount is compatible with both Func<Detail,int> and Func<Detail,double>. Ancak, dönüşümü ' ye dönüştürme ' Sum Func<Detail,int> den daha iyi olduğundan, aşırı yükleme çözümlemesi ilk yöntemi seçer Func<Detail,double> .However, overload resolution picks the first Sum method because the conversion to Func<Detail,int> is better than the conversion to Func<Detail,double>.

İkinci çağrısında orderDetails.Sum , Sum anonim işlev d => d.UnitPrice * d.UnitCount türünde bir değer ürettiğinden yalnızca ikinci yöntem geçerlidir double .In the second invocation of orderDetails.Sum, only the second Sum method is applicable because the anonymous function d => d.UnitPrice * d.UnitCount produces a value of type double. Bu nedenle, aşırı yükleme çözümlemesi Sum Bu çağrı için ikinci yöntemi seçer.Thus, overload resolution picks the second Sum method for that invocation.

Anonim işlevler ve dinamik bağlamaAnonymous functions and dynamic binding

Anonim bir işlev, dinamik olarak bağlı bir işlemin alıcısı, bağımsız değişkeni veya işleneni olamaz.An anonymous function cannot be a receiver, argument or operand of a dynamically bound operation.

Dış değişkenlerOuter variables

Kapsamı lambda_expression veya anonymous_method_expression içeren herhangi bir yerel değişken, değer parametresi veya parametre dizisine anonim işlevin dış değişkeni denir.Any local variable, value parameter, or parameter array whose scope includes the lambda_expression or anonymous_method_expression is called an outer variable of the anonymous function. Bir sınıfın örnek işlev üyesinde, this değer bir değer parametresi olarak kabul edilir ve işlev üyesi içinde bulunan herhangi bir anonim işlevin dış değişkenidir.In an instance function member of a class, the this value is considered a value parameter and is an outer variable of any anonymous function contained within the function member.

Yakalanan dış değişkenlerCaptured outer variables

Bir dış değişkene adsız bir işlev tarafından başvuruluyorsa, dış değişken anonim işlev tarafından yakalanarak bildirilir.When an outer variable is referenced by an anonymous function, the outer variable is said to have been captured by the anonymous function. Genellikle, yerel bir değişkenin ömrü, ilişkili olduğu blok veya deyimin yürütmesi ile sınırlıdır (yerel değişkenler).Ordinarily, the lifetime of a local variable is limited to execution of the block or statement with which it is associated (Local variables). Ancak, yakalanan bir dış değişkenin ömrü, anonim işlevden oluşturulan temsilci veya ifade ağacı çöp toplama için uygun hale gelene kadar en az genişletilir.However, the lifetime of a captured outer variable is extended at least until the delegate or expression tree created from the anonymous function becomes eligible for garbage collection.

ÖrnekteIn the example

using System;

delegate int D();

class Test
{
    static D F() {
        int x = 0;
        D result = () => ++x;
        return result;
    }

    static void Main() {
        D d = F();
        Console.WriteLine(d());
        Console.WriteLine(d());
        Console.WriteLine(d());
    }
}

Yerel değişken x anonim işlev tarafından yakalanır ve ömrü, ' x den döndürülen temsilci F çöp toplama için uygun hale gelene kadar (programın çok sonuna kadar gerçekleşmeyen) en az genişletilir.the local variable x is captured by the anonymous function, and the lifetime of x is extended at least until the delegate returned from F becomes eligible for garbage collection (which doesn't happen until the very end of the program). Anonymous işlevinin her çağrısı aynı örneği üzerinde çalışır x , örneğin çıktısı şu şekilde olur:Since each invocation of the anonymous function operates on the same instance of x, the output of the example is:

1
2
3

Yerel bir değişken veya bir değer parametresi anonim bir işlev tarafından yakalandıktan sonra, yerel değişken veya parametre artık sabit bir değişken (sabit ve taşınabilir değişkenler) olarak kabul edilmez, ancak bunun yerine taşınabilir bir değişken olarak kabul edilir.When a local variable or a value parameter is captured by an anonymous function, the local variable or parameter is no longer considered to be a fixed variable (Fixed and moveable variables), but is instead considered to be a moveable variable. Bu nedenle unsafe , yakalanan bir dış değişkenin adresini alan herhangi bir kodun, önce fixed değişkeni düzeltmesini sağlamak için ifadesini kullanması gerekir.Thus any unsafe code that takes the address of a captured outer variable must first use the fixed statement to fix the variable.

Yakalanamayan bir değişkenin aksine, yakalanan bir yerel değişkenin aynı anda birden fazla yürütme iş parçacığına sunulabileceğini unutmayın.Note that unlike an uncaptured variable, a captured local variable can be simultaneously exposed to multiple threads of execution.

Yerel değişkenlerin örneklenmesiInstantiation of local variables

Bir yerel değişken, yürütme değişkenin kapsamına girdiğinde örnek olarak değerlendirilir.A local variable is considered to be instantiated when execution enters the scope of the variable. Örneğin, aşağıdaki yöntem çağrıldığında, x her döngünün yinelemesi için bir kez olmak üzere yerel değişken örneği üç kez başlatılır.For example, when the following method is invoked, the local variable x is instantiated and initialized three times—once for each iteration of the loop.

static void F() {
    for (int i = 0; i < 3; i++) {
        int x = i * 2 + 1;
        ...
    }
}

Bununla birlikte, döngüsünün dışına bildirim taşımak, x tek bir örneklemede oluşur x :However, moving the declaration of x outside the loop results in a single instantiation of x:

static void F() {
    int x;
    for (int i = 0; i < 3; i++) {
        x = i * 2 + 1;
        ...
    }
}

Yakalanmadığı zaman, bir yerel değişkenin hangi sıklıkta örneklendirildiğini tam olarak gözlemleyebilmenin bir yolu yoktur. örneklemelerin yaşam süreleri kopuk olduğundan, her örnekleme için aynı depolama konumunu kullanmak mümkündür.When not captured, there is no way to observe exactly how often a local variable is instantiated—because the lifetimes of the instantiations are disjoint, it is possible for each instantiation to simply use the same storage location. Ancak, anonim bir işlev yerel bir değişken yakaladığında, örnekleme etkileri görünür hale gelir.However, when an anonymous function captures a local variable, the effects of instantiation become apparent.

ÖrnekteThe example

using System;

delegate void D();

class Test
{
    static D[] F() {
        D[] result = new D[3];
        for (int i = 0; i < 3; i++) {
            int x = i * 2 + 1;
            result[i] = () => { Console.WriteLine(x); };
        }
        return result;
    }

    static void Main() {
        foreach (D d in F()) d();
    }
}

çıktıyı üretir:produces the output:

1
3
5

Bununla birlikte, bildirimi x döngü dışına taşındığında:However, when the declaration of x is moved outside the loop:

static D[] F() {
    D[] result = new D[3];
    int x;
    for (int i = 0; i < 3; i++) {
        x = i * 2 + 1;
        result[i] = () => { Console.WriteLine(x); };
    }
    return result;
}

çıktı:the output is:

5
5
5

Bir for döngüsü bir yineleme değişkeni bildirirse, bu değişkenin kendisi döngünün dışında bildirildikleri kabul edilir.If a for-loop declares an iteration variable, that variable itself is considered to be declared outside of the loop. Bu nedenle, örnek yineleme değişkeninin kendisini yakalamak üzere değiştirilirse:Thus, if the example is changed to capture the iteration variable itself:

static D[] F() {
    D[] result = new D[3];
    for (int i = 0; i < 3; i++) {
        result[i] = () => { Console.WriteLine(i); };
    }
    return result;
}

yalnızca bir yineleme değişkeni örneği yakalanır, bu da çıktıyı üretir:only one instance of the iteration variable is captured, which produces the output:

3
3
3

Bazı yakalanan değişkenlerin paylaşılması için anonim işlev temsilcilerinin, hala diğerlerinin farklı örneklerine sahip olması mümkündür.It is possible for anonymous function delegates to share some captured variables yet have separate instances of others. Örneğin, F olarak değiştirilirseFor example, if F is changed to

static D[] F() {
    D[] result = new D[3];
    int x = 0;
    for (int i = 0; i < 3; i++) {
        int y = 0;
        result[i] = () => { Console.WriteLine("{0} {1}", ++x, ++y); };
    }
    return result;
}

üç temsilci aynı x ancak örneklerinin ayrı bir örneğini yakalar y ve çıktı şu şekilde olur:the three delegates capture the same instance of x but separate instances of y, and the output is:

1 1
2 1
3 1

Ayrı anonim işlevler, bir dış değişkenin aynı örneğini yakalayabilir.Separate anonymous functions can capture the same instance of an outer variable. Örnekte:In the example:

using System;

delegate void Setter(int value);

delegate int Getter();

class Test
{
    static void Main() {
        int x = 0;
        Setter s = (int value) => { x = value; };
        Getter g = () => { return x; };
        s(5);
        Console.WriteLine(g());
        s(10);
        Console.WriteLine(g());
    }
}

iki anonim işlev yerel değişkenin aynı örneğini yakalar x ve bu nedenle bu değişken ile "iletişim kurabilir".the two anonymous functions capture the same instance of the local variable x, and they can thus "communicate" through that variable. Örneğin çıktısı şu şekilde olur:The output of the example is:

5
10

Anonim işlev ifadelerinin değerlendirmesiEvaluation of anonymous function expressions

Anonim bir işlev F her zaman D E doğrudan veya temsilci oluşturma ifadesinin yürütülmesi aracılığıyla bir temsilci türüne veya bir ifade ağacı türüne dönüştürülmelidir new D(F) .An anonymous function F must always be converted to a delegate type D or an expression tree type E, either directly or through the execution of a delegate creation expression new D(F). Bu dönüştürme, anonim işlev dönüştürmeleribölümünde açıklandığı gibi anonim işlevin sonucunu belirler.This conversion determines the result of the anonymous function, as described in Anonymous function conversions.

Sorgu ifadeleriQuery expressions

Sorgu ifadeleri , SQL ve XQuery gibi ilişkisel ve hiyerarşik sorgu dillerine benzer sorgular için dil ile tümleşik bir sözdizimi sağlar.Query expressions provide a language integrated syntax for queries that is similar to relational and hierarchical query languages such as SQL and XQuery.

query_expression
    : from_clause query_body
    ;

from_clause
    : 'from' type? identifier 'in' expression
    ;

query_body
    : query_body_clauses? select_or_group_clause query_continuation?
    ;

query_body_clauses
    : query_body_clause
    | query_body_clauses query_body_clause
    ;

query_body_clause
    : from_clause
    | let_clause
    | where_clause
    | join_clause
    | join_into_clause
    | orderby_clause
    ;

let_clause
    : 'let' identifier '=' expression
    ;

where_clause
    : 'where' boolean_expression
    ;

join_clause
    : 'join' type? identifier 'in' expression 'on' expression 'equals' expression
    ;

join_into_clause
    : 'join' type? identifier 'in' expression 'on' expression 'equals' expression 'into' identifier
    ;

orderby_clause
    : 'orderby' orderings
    ;

orderings
    : ordering (',' ordering)*
    ;

ordering
    : expression ordering_direction?
    ;

ordering_direction
    : 'ascending'
    | 'descending'
    ;

select_or_group_clause
    : select_clause
    | group_clause
    ;

select_clause
    : 'select' expression
    ;

group_clause
    : 'group' expression 'by' expression
    ;

query_continuation
    : 'into' identifier query_body
    ;

Sorgu ifadesi bir from yan tümcesiyle başlar ve select or group yan tümcesiyle biter.A query expression begins with a from clause and ends with either a select or group clause. Başlangıç from yan tümcesinin arkasından sıfır veya daha fazla,, from let where join veya orderby yan tümce gelebilir.The initial from clause can be followed by zero or more from, let, where, join or orderby clauses. Her from yan tümce, _ dizisi * öğelerinin üzerinde değişen bir *Range değişkeni _ sunan bir Oluşturucu.Each from clause is a generator introducing a range variable _ which ranges over the elements of a _sequence**. Her let yan tümce, önceki Aralık değişkenlerine göre hesaplanan bir değeri temsil eden bir Aralık değişkeni tanıtır.Each let clause introduces a range variable representing a value computed by means of previous range variables. Her where yan tümce, sonuçtan öğeleri dışlayan bir filtredir.Each where clause is a filter that excludes items from the result. Her join yan tümce, eşleşen çiftleri oluşturan kaynak dizinin belirtilen anahtarlarını başka bir dizinin anahtarlarıyla karşılaştırır.Each join clause compares specified keys of the source sequence with keys of another sequence, yielding matching pairs. Her orderby yan tümce öğeleri belirtilen ölçütlere göre yeniden sıralar. Final select veya group yan tümcesi, Aralık değişkenleri açısından sonucun şeklini belirtir.Each orderby clause reorders items according to specified criteria.The final select or group clause specifies the shape of the result in terms of the range variables. Son olarak, bir into yan tümce, bir sorgunun sonuçlarını sonraki bir sorguda Oluşturucu olarak düşünerek "splice" sorguları için kullanılabilir.Finally, an into clause can be used to "splice" queries by treating the results of one query as a generator in a subsequent query.

Sorgu ifadelerinde belirsizlikleriAmbiguities in query expressions

Sorgu ifadeleri, belirli bir bağlamda özel anlamı olan tanımlayıcılar içeren bir dizi "bağlamsal anahtar sözcük", yani.Query expressions contain a number of "contextual keywords", i.e., identifiers that have special meaning in a given context. Özellikle,,,,,, from where join on equals into let , orderby , ascending , descending , select , group ve by .Specifically these are from, where, join, on, equals, into, let, orderby, ascending, descending, select, group and by. Bu tanımlayıcıların, anahtar sözcük veya basit adlar olarak karışık olarak kullanılması nedeniyle sorgu ifadelerinde belirsizlikleri kaçınmak için, bu tanımlayıcılar bir sorgu ifadesinin içinde herhangi bir yerde olduğunda anahtar sözcük olarak kabul edilir.In order to avoid ambiguities in query expressions caused by mixed use of these identifiers as keywords or simple names, these identifiers are considered keywords when occurring anywhere within a query expression.

Bu amaçla, bir sorgu ifadesi "" ile başlayan herhangi bir ifadedir ve " from identifier ; ", " = " veya "" dışında herhangi bir belirteç izler , .For this purpose, a query expression is any expression that starts with "from identifier" followed by any token except ";", "=" or ",".

Bu sözcüklerin bir sorgu ifadesinde tanımlayıcı olarak kullanılabilmesi için, " @ " (tanımlayıcılar) ön eki uygulanabilir.In order to use these words as identifiers within a query expression, they can be prefixed with "@" (Identifiers).

Sorgu ifadesi çevirisiQuery expression translation

C# dili sorgu ifadelerinin yürütme semantiğini belirtmez.The C# language does not specify the execution semantics of query expressions. Bunun yerine sorgu ifadeleri sorgu ifade düzenine (sorgu ifade deseninin) bağlı olan yöntemlerin etkinleştirilmesinde çevrilir.Rather, query expressions are translated into invocations of methods that adhere to the query expression pattern (The query expression pattern). Özellikle, sorgu ifadeleri,,,,,,, Where Select SelectMany Join GroupJoin OrderBy OrderByDescending ThenBy , ThenByDescending ,, GroupBy ve Cast adlı yöntemlerin çağırmaları olarak çevrilir. Sorgu ifadesidüzeninde açıklandığı gibi, bu yöntemlerin belirli imzaları ve sonuç türlerini olması beklenir.Specifically, query expressions are translated into invocations of methods named Where, Select, SelectMany, Join, GroupJoin, OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, and Cast.These methods are expected to have particular signatures and result types, as described in The query expression pattern. Bu yöntemler, sorgulanan nesnenin örnek yöntemleri veya nesne dışındaki genişletme yöntemleri olabilir ve sorgunun gerçek yürütmesini uygular.These methods can be instance methods of the object being queried or extension methods that are external to the object, and they implement the actual execution of the query.

Sorgu ifadelerinden Yöntem etkinleştirmeleri 'e yapılan çeviri, herhangi bir tür bağlama veya aşırı yükleme çözümlemesi yapılmadan önce oluşan bir sözdizimsel eşleme olur.The translation from query expressions to method invocations is a syntactic mapping that occurs before any type binding or overload resolution has been performed. Çevirinin sözdizimsel olarak doğru olması garanti edilir, ancak anlamsal olarak doğru C# kodu oluşturmak garanti edilmez.The translation is guaranteed to be syntactically correct, but it is not guaranteed to produce semantically correct C# code. Sorgu ifadelerinin çevirisinde, sonuçta elde edilen yöntem çağrıları normal Yöntem etkinleştirmeleri olarak işlenir ve bu, örneğin Yöntemler yoksa, bağımsız değişkenlerin yanlış türleri varsa veya yöntemler genel ise ve tür çıkarımı başarısız olursa, hataları açabilir.Following translation of query expressions, the resulting method invocations are processed as regular method invocations, and this may in turn uncover errors, for example if the methods do not exist, if arguments have wrong types, or if the methods are generic and type inference fails.

Bir sorgu ifadesi, daha fazla azaltmayı mümkün olana kadar, aşağıdaki Çeviriler tekrar tekrar uygulanarak işlenir.A query expression is processed by repeatedly applying the following translations until no further reductions are possible. Çeviriler uygulama sırasıyla listelenir: her bölümde, yukarıdaki bölümlerdeki çevirilerin tüketilildiği ve tükendiğinde, bir bölümün aynı sorgu ifadesinin işlenmesinde daha sonra yeniden ziyaret edilmesinin varsayıldığı varsayılır.The translations are listed in order of application: each section assumes that the translations in the preceding sections have been performed exhaustively, and once exhausted, a section will not later be revisited in the processing of the same query expression.

Sorgu ifadelerinde Aralık değişkenlerine atamaya izin verilmez.Assignment to range variables is not allowed in query expressions. Ancak, burada sunulan sözdizimsel çeviri düzeninde bazı durumlarda mümkün olmaması gerektiğinden, C# uygulamasının bu kısıtlamayı her zaman zorlamamasına izin verilir.However a C# implementation is permitted to not always enforce this restriction, since this may sometimes not be possible with the syntactic translation scheme presented here.

Belirli Çeviriler, tarafından belirtilen saydam tanımlayıcılarla Aralık değişkenlerini ekler * .Certain translations inject range variables with transparent identifiers denoted by *. Saydam tanımlayıcıların özel özellikleri, saydam tanımlayıcılarladaha ayrıntılı bir şekilde ele alınmıştır.The special properties of transparent identifiers are discussed further in Transparent identifiers.

Devamlılıklarla seçim ve GroupBy yan tümceleriSelect and groupby clauses with continuations

Devam eden bir sorgu ifadesiA query expression with a continuation

from ... into x ...

çevriliris translated into

from x in ( from ... ) ...

Aşağıdaki bölümlerde yer alan Çeviriler, sorguların into devamlılıklar olmadığını varsayar.The translations in the following sections assume that queries have no into continuations.

ÖrnekteThe example

from c in customers
group c by c.Country into g
select new { Country = g.Key, CustCount = g.Count() }

çevriliris translated into

from g in
    from c in customers
    group c by c.Country
select new { Country = g.Key, CustCount = g.Count() }

son çevirithe final translation of which is

customers.
GroupBy(c => c.Country).
Select(g => new { Country = g.Key, CustCount = g.Count() })

Açık Aralık değişken türleriExplicit range variable types

fromAçıkça bir Aralık değişkeni türünü belirten yan tümceA from clause that explicitly specifies a range variable type

from T x in e

çevriliris translated into

from x in ( e ) . Cast < T > ( )

joinAçıkça bir Aralık değişkeni türünü belirten yan tümceA join clause that explicitly specifies a range variable type

join T x in e on k1 equals k2

çevriliris translated into

join x in ( e ) . Cast < T > ( ) on k1 equals k2

Aşağıdaki bölümlerde yer alan Çeviriler, sorguların hiçbir açık Aralık değişken türüne sahip olmadığını varsayar.The translations in the following sections assume that queries have no explicit range variable types.

ÖrnekteThe example

from Customer c in customers
where c.City == "London"
select c

çevriliris translated into

from c in customers.Cast<Customer>()
where c.City == "London"
select c

son çevirithe final translation of which is

customers.
Cast<Customer>().
Where(c => c.City == "London")

Açık Aralık değişkeni türleri genel olmayan IEnumerable arabirimi uygulayan, ancak genel arabirimi olmayan koleksiyonları sorgulamak için yararlıdır IEnumerable<T> .Explicit range variable types are useful for querying collections that implement the non-generic IEnumerable interface, but not the generic IEnumerable<T> interface. Yukarıdaki örnekte bu durum, türünde ise olur customers ArrayList .In the example above, this would be the case if customers were of type ArrayList.

Sorgu ifadeleri oluşturmayı kaldırmaDegenerate query expressions

Formun sorgu ifadesiA query expression of the form

from x in e select x

çevriliris translated into

( e ) . Select ( x => x )

ÖrnekteThe example

from c in customers
select c

çevriliris translated into

customers.Select(c => c)

Bir bozuk sorgu ifadesi, kaynağın öğelerini önemli bir şekilde seçen bir ifadedir.A degenerate query expression is one that trivially selects the elements of the source. Çevirinin daha sonraki bir aşaması, diğer çeviri adımları tarafından tanıtılan ve kaynakları kendi kaynağıyla değiştirerek çıkartılmış olan sorgu kaldırma işlemleri kaldırır.A later phase of the translation removes degenerate queries introduced by other translation steps by replacing them with their source. Sorgu ifadesinin sonucunun, sorgunun istemcisinin türünü ve kimliğini açığa çıkardığından, hiçbir şekilde kaynak nesnenin kendisi olduğundan emin olmak önemlidir.It is important however to ensure that the result of a query expression is never the source object itself, as that would reveal the type and identity of the source to the client of the query. Bu nedenle bu adım, doğrudan kaynak kodunda yazılmış sorguları kaynak üzerinde açıkça çağırarak kaldırır Select .Therefore this step protects degenerate queries written directly in source code by explicitly calling Select on the source. Daha sonra Select Bu yöntemlerin kaynak nesnenin kendisini döndürmemesini sağlamak için, ve diğer sorgu işleçleri uygulayıcılarına kadar.It is then up to the implementers of Select and other query operators to ensure that these methods never return the source object itself.

Kimden, Let, WHERE, JOIN ve OrderBy yan tümceleriFrom, let, where, join and orderby clauses

İkinci from yan tümcesine ve ardından select yan tümcesine sahip bir sorgu ifadesiA query expression with a second from clause followed by a select clause

from x1 in e1
from x2 in e2
select v

çevriliris translated into

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )

İkinci yan tümcesine sahip bir sorgu ifadesi from ve ardından yan tümce dışında bir öğe select .A query expression with a second from clause followed by something other than a select clause:

from x1 in e1
from x2 in e2
...

çevriliris translated into

from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )
...

Yan tümcesiyle bir sorgu ifadesi letA query expression with a let clause

from x in e
let y = f
...

çevriliris translated into

from * in ( e ) . Select ( x => new { x , y = f } )
...

Yan tümcesiyle bir sorgu ifadesi whereA query expression with a where clause

from x in e
where f
...

çevriliris translated into

from x in ( e ) . Where ( x => f )
...

Yan tümcesi join into ve arkasından yan tümce içermeyen bir sorgu ifadesi selectA query expression with a join clause without an into followed by a select clause

from x1 in e1
join x2 in e2 on k1 equals k2
select v

çevriliris translated into

( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )

Yan tümcesi dışında bir join yan tümcesi içeren bir sorgu ifadesi into selectA query expression with a join clause without an into followed by something other than a select clause

from x1 in e1
join x2 in e2 on k1 equals k2
...

çevriliris translated into

from * in ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
...

join into Yan tümcesini izleyen yan tümcesiyle bir sorgu ifadesi selectA query expression with a join clause with an into followed by a select clause

from x1 in e1
join x2 in e2 on k1 equals k2 into g
select v

çevriliris translated into

( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )

join into Yan tümcesi dışında bir yan tümcesi içeren bir sorgu ifadesi selectA query expression with a join clause with an into followed by something other than a select clause

from x1 in e1
join x2 in e2 on k1 equals k2 into g
...

çevriliris translated into

from * in ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
...

Yan tümcesiyle bir sorgu ifadesi orderbyA query expression with an orderby clause

from x in e
orderby k1 , k2 , ..., kn
...

çevriliris translated into

from x in ( e ) . 
OrderBy ( x => k1 ) . 
ThenBy ( x => k2 ) .
... .
ThenBy ( x => kn )
...

Bir sıralama yan tümcesi bir descending yön göstergesi belirtiyorsa OrderByDescending bunun yerine veya çağrısı oluşturulur ThenByDescending .If an ordering clause specifies a descending direction indicator, an invocation of OrderByDescending or ThenByDescending is produced instead.

Aşağıdaki Çeviriler,, let where , join veya orderby yan tümcelerinin olmadığını ve from her sorgu ifadesinde bir başlangıç yan tümcesinin daha fazla olmadığını varsayar.The following translations assume that there are no let, where, join or orderby clauses, and no more than the one initial from clause in each query expression.

ÖrnekteThe example

from c in customers
from o in c.Orders
select new { c.Name, o.OrderID, o.Total }

çevriliris translated into

customers.
SelectMany(c => c.Orders,
     (c,o) => new { c.Name, o.OrderID, o.Total }
)

ÖrnekteThe example

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

çevriliris translated into

from * in customers.
    SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }

son çevirithe final translation of which is

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.OrderID, x.o.Total })

x, aksi takdirde görünmeyen ve erişilemeyen bir derleyicinin ürettiği tanımlayıcı.where x is a compiler generated identifier that is otherwise invisible and inaccessible.

ÖrnekteThe example

from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new { o.OrderID, Total = t }

çevriliris translated into

from * in orders.
    Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) })
where t >= 1000 
select new { o.OrderID, Total = t }

son çevirithe final translation of which is

orders.
Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) }).
Where(x => x.t >= 1000).
Select(x => new { x.o.OrderID, Total = x.t })

x, aksi takdirde görünmeyen ve erişilemeyen bir derleyicinin ürettiği tanımlayıcı.where x is a compiler generated identifier that is otherwise invisible and inaccessible.

ÖrnekteThe example

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new { c.Name, o.OrderDate, o.Total }

çevriliris translated into

customers.Join(orders, c => c.CustomerID, o => o.CustomerID,
    (c, o) => new { c.Name, o.OrderDate, o.Total })

ÖrnekteThe example

from c in customers
join o in orders on c.CustomerID equals o.CustomerID into co
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }

çevriliris translated into

from * in customers.
    GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
        (c, co) => new { c, co })
let n = co.Count()
where n >= 10 
select new { c.Name, OrderCount = n }

son çevirithe final translation of which is

customers.
GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
    (c, co) => new { c, co }).
Select(x => new { x, n = x.co.Count() }).
Where(y => y.n >= 10).
Select(y => new { y.x.c.Name, OrderCount = y.n)

Burada x ve y derleyicinin oluşturduğu tanımlayıcılar, aksi halde görünmez ve erişilemez.where x and y are compiler generated identifiers that are otherwise invisible and inaccessible.

ÖrnekteThe example

from o in orders
orderby o.Customer.Name, o.Total descending
select o

Son çeviriyi içerirhas the final translation

orders.
OrderBy(o => o.Customer.Name).
ThenByDescending(o => o.Total)

Yan tümceleri SeçSelect clauses

Formun sorgu ifadesiA query expression of the form

from x in e select v

çevriliris translated into

( e ) . Select ( x => v )

v 'nin x tanımlayıcısı olduğu durumlar dışında, çeviri yalnızcaexcept when v is the identifier x, the translation is simply

( e )

Örneğin:For example

from c in customers.Where(c => c.City == "London")
select c

yalnızca şuna çevriliris simply translated into

customers.Where(c => c.City == "London")

GroupBy yan tümceleriGroupby clauses

Formun sorgu ifadesiA query expression of the form

from x in e group v by k

çevriliris translated into

( e ) . GroupBy ( x => k , x => v )

v 'nin x tanımlayıcısı olduğu durumlar dışında, çeviriexcept when v is the identifier x, the translation is

( e ) . GroupBy ( x => k )

ÖrnekteThe example

from c in customers
group c.Name by c.Country

çevriliris translated into

customers.
GroupBy(c => c.Country, c => c.Name)

Saydam tanımlayıcılarTransparent identifiers

Belirli Çeviriler, Aralık değişkenlerini tarafından belirtilen *saydam tanımlayıcılar _ ile ekler _ .Certain translations inject range variables with *transparent identifiers _ denoted by _. Saydam tanımlayıcılar uygun bir dil özelliği değildir; Bunlar yalnızca sorgu ifadesi çevirisi işleminde bir ara adım olarak mevcuttur.Transparent identifiers are not a proper language feature; they exist only as an intermediate step in the query expression translation process.

Bir sorgu çevirisi bir saydam tanımlayıcıyı geçersiz kılar, ek çeviri adımları saydam tanımlayıcıyı anonim işlevlere ve anonim nesne başlatıcılarına yayar.When a query translation injects a transparent identifier, further translation steps propagate the transparent identifier into anonymous functions and anonymous object initializers. Bu bağlamlarda saydam tanımlayıcılar aşağıdaki davranışa sahiptir:In those contexts, transparent identifiers have the following behavior:

  • Bir saydam tanımlayıcı, anonim bir işlevde parametre olarak gerçekleştiğinde, ilişkili anonim türün üyeleri anonim işlevin gövdesinde otomatik olarak kapsam içinde olur.When a transparent identifier occurs as a parameter in an anonymous function, the members of the associated anonymous type are automatically in scope in the body of the anonymous function.
  • Saydam tanımlayıcısı olan bir üye kapsam içinde olduğunda, o üyenin üyeleri de kapsam içinde olur.When a member with a transparent identifier is in scope, the members of that member are in scope as well.
  • Bir saydam tanımlayıcı, anonim nesne başlatıcısında bir üye bildirimci olarak oluştuğunda, saydam tanımlayıcı içeren bir üye tanıtır.When a transparent identifier occurs as a member declarator in an anonymous object initializer, it introduces a member with a transparent identifier.
  • Yukarıda açıklanan çeviri adımlarında, saydam tanımlayıcılar her zaman anonim türlerle birlikte tanıtılmıştır ve birden çok Aralık değişkenini tek bir nesnenin üyeleri olarak yakalama amacını taşıyan bir şekilde.In the translation steps described above, transparent identifiers are always introduced together with anonymous types, with the intent of capturing multiple range variables as members of a single object. C# uygulamasının birden çok Aralık değişkenini gruplamak için anonim türlerden farklı bir mekanizma kullanmasına izin verilir.An implementation of C# is permitted to use a different mechanism than anonymous types to group together multiple range variables. Aşağıdaki çeviri örnekleri, anonim türlerin kullanıldığını varsayar ve saydam tanımlayıcıların nasıl çevrilebilmesi gerektiğini gösterir.The following translation examples assume that anonymous types are used, and show how transparent identifiers can be translated away.

ÖrnekteThe example

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }

çevriliris translated into

from * in customers.
    SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }

daha fazla çevrilmişwhich is further translated into

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(* => o.Total).
Select(* => new { c.Name, o.Total })

saydam tanımlayıcılar silindiklerinde, eşittirwhich, when transparent identifiers are erased, is equivalent to

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.Total })

x, aksi takdirde görünmeyen ve erişilemeyen bir derleyicinin ürettiği tanımlayıcı.where x is a compiler generated identifier that is otherwise invisible and inaccessible.

ÖrnekteThe example

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

çevriliris translated into

from * in customers.
    Join(orders, c => c.CustomerID, o => o.CustomerID, 
        (c, o) => new { c, o })
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

daha azwhich is further reduced to

customers.
Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }).
Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d }).
Join(products, * => d.ProductID, p => p.ProductID, (*, p) => new { *, p }).
Select(* => new { c.Name, o.OrderDate, p.ProductName })

son çevirithe final translation of which is

customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
    (c, o) => new { c, o }).
Join(details, x => x.o.OrderID, d => d.OrderID,
    (x, d) => new { x, d }).
Join(products, y => y.d.ProductID, p => p.ProductID,
    (y, p) => new { y, p }).
Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })

Burada x , y , ve, z Aksi durumda görünmeyen ve erişilemeyen derleyici tarafından oluşturulan tanımlayıcılardır.where x, y, and z are compiler generated identifiers that are otherwise invisible and inaccessible.

Sorgu ifadesi desenininThe query expression pattern

Sorgu ifadesi stili , sorgu ifadelerini desteklemek için uygulayabileceğiniz yöntemlerin bir modelini oluşturur.The Query expression pattern establishes a pattern of methods that types can implement to support query expressions. Sorgu ifadeleri, sözdizimsel eşleme yoluyla Yöntem etkinleştirmeleri 'e çevrildiği için, türlerin sorgu ifadesi deseninin nasıl uygulandığı konusunda önemli ölçüde esneklik vardır.Because query expressions are translated to method invocations by means of a syntactic mapping, types have considerable flexibility in how they implement the query expression pattern. Örneğin, iki aynı çağırma söz dizimini içerdiğinden ve Yöntemler, anonim işlevler her ikisine de dönüştürülebildiğinden temsilci veya ifade ağaçları isteyebildiğinden, düzenin yöntemleri örnek yöntemleri veya genişletme yöntemleri olarak uygulanabilir.For example, the methods of the pattern can be implemented as instance methods or as extension methods because the two have the same invocation syntax, and the methods can request delegates or expression trees because anonymous functions are convertible to both.

Sorgu ifadesi modelini destekleyen bir genel türün önerilen şekli C<T> aşağıda gösterilmiştir.The recommended shape of a generic type C<T> that supports the query expression pattern is shown below. Parametre ve sonuç türleri arasındaki uygun ilişkileri göstermek için genel bir tür kullanılır, ancak genel olmayan türler için de düzeni uygulamak mümkündür.A generic type is used in order to illustrate the proper relationships between parameter and result types, but it is possible to implement the pattern for non-generic types as well.

delegate R Func<T1,R>(T1 arg1);

delegate R Func<T1,T2,R>(T1 arg1, T2 arg2);

class C
{
    public C<T> Cast<T>();
}

class C<T> : C
{
    public C<T> Where(Func<T,bool> predicate);

    public C<U> Select<U>(Func<T,U> selector);

    public C<V> SelectMany<U,V>(Func<T,C<U>> selector,
        Func<T,U,V> resultSelector);

    public C<V> Join<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
        Func<U,K> innerKeySelector, Func<T,U,V> resultSelector);

    public C<V> GroupJoin<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
        Func<U,K> innerKeySelector, Func<T,C<U>,V> resultSelector);

    public O<T> OrderBy<K>(Func<T,K> keySelector);

    public O<T> OrderByDescending<K>(Func<T,K> keySelector);

    public C<G<K,T>> GroupBy<K>(Func<T,K> keySelector);

    public C<G<K,E>> GroupBy<K,E>(Func<T,K> keySelector,
        Func<T,E> elementSelector);
}

class O<T> : C<T>
{
    public O<T> ThenBy<K>(Func<T,K> keySelector);

    public O<T> ThenByDescending<K>(Func<T,K> keySelector);
}

class G<K,T> : C<T>
{
    public K Key { get; }
}

Yukarıdaki yöntemler genel temsilci türlerini kullanır Func<T1,R> Func<T1,T2,R> , ancak parametre ve sonuç türlerinde aynı ilişkilerle diğer temsilci veya ifade ağacı türleri de aynı şekilde kullanılabilir.The methods above use the generic delegate types Func<T1,R> and Func<T1,T2,R>, but they could equally well have used other delegate or expression tree types with the same relationships in parameter and result types.

C<T>Ve O<T> ThenBy ThenByDescending yöntemlerinin yalnızca veya sonucu üzerinde kullanılabilir olmasını sağlayan ve OrderBy arasındaki önerilen ilişkiye dikkat edin OrderByDescending .Notice the recommended relationship between C<T> and O<T> which ensures that the ThenBy and ThenByDescending methods are available only on the result of an OrderBy or OrderByDescending. Ayrıca GroupBy , her bir iç sıranın ek bir özelliği olduğu, bir dizi sıranın (bir dizi sıra) önerilen şekline de dikkat edin Key .Also notice the recommended shape of the result of GroupBy -- a sequence of sequences, where each inner sequence has an additional Key property.

System.LinqAd alanı, arabirimini uygulayan herhangi bir tür için sorgu işleci deseninin bir uygulamasını sağlar System.Collections.Generic.IEnumerable<T> .The System.Linq namespace provides an implementation of the query operator pattern for any type that implements the System.Collections.Generic.IEnumerable<T> interface.

Atama işleçleriAssignment operators

Atama işleçleri bir değişkene, özelliğe, olaya veya Dizin Oluşturucu öğesine yeni bir değer atar.The assignment operators assign a new value to a variable, a property, an event, or an indexer element.

assignment
    : unary_expression assignment_operator expression
    ;

assignment_operator
    : '='
    | '+='
    | '-='
    | '*='
    | '/='
    | '%='
    | '&='
    | '|='
    | '^='
    | '<<='
    | right_shift_assignment
    ;

Atamanın sol işleneni, değişken olarak sınıflandırılmış bir ifade, özellik erişimi, Dizin Oluşturucu erişimi veya olay erişimi olmalıdır.The left operand of an assignment must be an expression classified as a variable, a property access, an indexer access, or an event access.

=İşleci basit atama işleci olarak adlandırılır.The = operator is called the simple assignment operator. Sağ işlenenin değerini, sol işlenen tarafından verilen değişken, özellik veya Dizin Oluşturucu öğesine atar.It assigns the value of the right operand to the variable, property, or indexer element given by the left operand. Basit atama işlecinin sol işleneni bir olay erişimi olmayabilir ( alan benzeri olaylarbölümünde açıklananlar dışında).The left operand of the simple assignment operator may not be an event access (except as described in Field-like events). Basit atama işleci basit atamadaaçıklanmıştır.The simple assignment operator is described in Simple assignment.

İşleç dışındaki atama işleçleri = bileşik atama işleçleri olarak adlandırılır.The assignment operators other than the = operator are called the compound assignment operators. Bu işleçler iki işlenen üzerinde belirtilen işlemi gerçekleştirir ve ardından sonuçtaki değeri, sol işlenen tarafından verilen değişken, özellik veya Dizin Oluşturucu öğesine atar.These operators perform the indicated operation on the two operands, and then assign the resulting value to the variable, property, or indexer element given by the left operand. Bileşik atama işleçleri Birleşik atamabölümünde açıklanmıştır.The compound assignment operators are described in Compound assignment.

+= -= Sol işlenen olarak bir olay erişim ifadesi olan ve işleçleri olay atama işleçleri olarak adlandırılır.The += and -= operators with an event access expression as the left operand are called the event assignment operators. Sol işlenen olarak bir olay erişimiyle hiçbir başka atama işleci geçerli değildir.No other assignment operator is valid with an event access as the left operand. Olay atama işleçleri olay atamasındaaçıklanmaktadır.The event assignment operators are described in Event assignment.

Atama işleçleri doğru ilişkilendirilebilir, yani işlemler sağdan sola gruplandırılır.The assignment operators are right-associative, meaning that operations are grouped from right to left. Örneğin, formun bir ifadesi a = b = c olarak değerlendirilir a = (b = c) .For example, an expression of the form a = b = c is evaluated as a = (b = c).

Basit atamaSimple assignment

=İşleci basit atama işleci olarak adlandırılır.The = operator is called the simple assignment operator.

Basit bir atamanın sol işleneni formundadır E.P veya E[Ei] nerede E derleme zamanı türünde olursa dynamic atama, dinamik olarak bağlanır (dinamik bağlama).If the left operand of a simple assignment is of the form E.P or E[Ei] where E has the compile-time type dynamic, then the assignment is dynamically bound (Dynamic binding). Bu durumda, atama ifadesinin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm çalışma zamanı türüne göre çalışma zamanında gerçekleşmeyecektir E .In this case the compile-time type of the assignment expression is dynamic, and the resolution described below will take place at run-time based on the run-time type of E.

Basit bir atamada, sağ işlenen, sol işlenenin türüne örtük olarak dönüştürülebilir bir ifade olmalıdır.In a simple assignment, the right operand must be an expression that is implicitly convertible to the type of the left operand. İşlem, sol işlenen tarafından verilen değişken, özellik veya Dizin Oluşturucu öğesine sağ işlenenin değerini atar.The operation assigns the value of the right operand to the variable, property, or indexer element given by the left operand.

Basit atama ifadesinin sonucu, sol işlenene atanan değerdir.The result of a simple assignment expression is the value assigned to the left operand. Sonuç, sol işleneniyle aynı türe sahiptir ve her zaman bir değer olarak sınıflandırılır.The result has the same type as the left operand and is always classified as a value.

Sol işlenen bir özellik veya Dizin Oluşturucu erişimi ise, özelliğin veya dizin oluşturucunun bir set erişimcisi olmalıdır.If the left operand is a property or indexer access, the property or indexer must have a set accessor. Bu durumda, bir bağlama zamanı hatası oluşur.If this is not the case, a binding-time error occurs.

Formun basit atamasının çalışma zamanı işleme x = y aşağıdaki adımlardan oluşur:The run-time processing of a simple assignment of the form x = y consists of the following steps:

  • xBir değişken olarak sınıflandırıldıysanız:If x is classified as a variable:
    • x değişkeni üretmek için değerlendirilir.x is evaluated to produce the variable.
    • y değerlendirilir ve gerekirse x örtük bir dönüştürme (örtük dönüştürmeler) ile türüne dönüştürülür.y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
    • Tarafından verilen değişken bir x reference_type dizi öğesidir, için hesaplanan değerin y öğesi olan dizi örneğiyle uyumlu olduğundan emin olmak için bir çalışma zamanı denetimi yapılır x .If the variable given by x is an array element of a reference_type, a run-time check is performed to ensure that the value computed for y is compatible with the array instance of which x is an element. Eğer ise denetim başarılı y olur null ya da tarafından başvurulan örneğin gerçek türünden bir örtük başvuru dönüştürmesi (örtük başvuru dönüştürmeleri) varsa, y içeren dizi örneğinin gerçek öğe türüne x .The check succeeds if y is null, or if an implicit reference conversion (Implicit reference conversions) exists from the actual type of the instance referenced by y to the actual element type of the array instance containing x. Aksi takdirde, bir System.ArrayTypeMismatchException oluşturulur.Otherwise, a System.ArrayTypeMismatchException is thrown.
    • Değerlendirmesinin ve dönüştürmesinden kaynaklanan değer, y değerlendirmesi tarafından verilen konuma depolanır x .The value resulting from the evaluation and conversion of y is stored into the location given by the evaluation of x.
  • xÖzellik veya Dizin Oluşturucu erişimi olarak sınıflandırıldıysanız:If x is classified as a property or indexer access:
    • İle ilişkili örnek ifadesi (değilse x static ) ve bağımsız değişken listesi ( x bir Dizin Oluşturucu erişimsiyse) x değerlendirilir ve sonuçlar sonraki set erişimci çağrısında kullanılır.The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent set accessor invocation.
    • y değerlendirilir ve gerekirse x örtük bir dönüştürme (örtük dönüştürmeler) ile türüne dönüştürülür.y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
    • setErişimcisi, x y bağımsız değişkeni olarak hesaplanan değerle çağrılır value .The set accessor of x is invoked with the value computed for y as its value argument.

Dizi birlikte değişim kuralları (dizi Kovaryans), bir dizi türünün değerine A[] , bir dizi türünün bir örneğine B[] , öğesinden bir örtük başvuru dönüştürmesi sağlanmış olarak izin verir B A .The array co-variance rules (Array covariance) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. Bu kurallar nedeniyle, bir reference_type dizi öğesine atama, atanmakta olan değerin dizi örneğiyle uyumlu olduğundan emin olmak için bir çalışma zamanı denetimi gerektirir.Because of these rules, assignment to an array element of a reference_type requires a run-time check to ensure that the value being assigned is compatible with the array instance. ÖrnekteIn the example

string[] sa = new string[10];
object[] oa = sa;

oa[0] = null;               // Ok
oa[1] = "Hello";            // Ok
oa[2] = new ArrayList();    // ArrayTypeMismatchException

öğesinin bir System.ArrayTypeMismatchException örneği ArrayList bir öğesi içinde depolanamadığından, son atama bir öğesinin oluşturulmasına neden olur string[] .the last assignment causes a System.ArrayTypeMismatchException to be thrown because an instance of ArrayList cannot be stored in an element of a string[].

Bir struct_type içinde bildirildiği bir özellik veya Dizin Oluşturucu bir atamanın hedefi olduğunda, özellik veya Dizin Oluşturucu erişimi ile ilişkili örnek ifadesi bir değişken olarak sınıflandırılmalıdır.When a property or indexer declared in a struct_type is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. Örnek ifadesi bir değer olarak sınıflandırılasiyse, bağlama zamanı hatası oluşur.If the instance expression is classified as a value, a binding-time error occurs. Üye erişiminedeniyle aynı kural alanlar için de geçerli olur.Because of Member access, the same rule also applies to fields.

Bildirimler verildi:Given the declarations:

struct Point
{
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int X {
        get { return x; }
        set { x = value; }
    }

    public int Y {
        get { return y; }
        set { y = value; }
    }
}

struct Rectangle
{
    Point a, b;

    public Rectangle(Point a, Point b) {
        this.a = a;
        this.b = b;
    }

    public Point A {
        get { return a; }
        set { a = value; }
    }

    public Point B {
        get { return b; }
        set { b = value; }
    }
}

örnektein the example

Point p = new Point();
p.X = 100;
p.Y = 100;
Rectangle r = new Rectangle();
r.A = new Point(10, 10);
r.B = p;

,, ve için atamalara p.X p.Y r.A r.B izin verilir çünkü p ve r değişkenleri.the assignments to p.X, p.Y, r.A, and r.B are permitted because p and r are variables. Ancak, örnekteHowever, in the example

Rectangle r = new Rectangle();
r.A.X = 10;
r.A.Y = 10;
r.B.X = 100;
r.B.Y = 100;

Atamalar, bu yana r.A ve r.B değişkenleri olmadığından geçersizdir.the assignments are all invalid, since r.A and r.B are not variables.

Bileşik atamaCompound assignment

Bileşik atamanın sol işleneni formundadır E.P veya E[Ei] nerede E derleme zamanı türü varsa dynamic , atama dinamik olarak bağlanır (dinamik bağlama).If the left operand of a compound assignment is of the form E.P or E[Ei] where E has the compile-time type dynamic, then the assignment is dynamically bound (Dynamic binding). Bu durumda, atama ifadesinin derleme zamanı türü olur dynamic ve aşağıda açıklanan çözüm çalışma zamanı türüne göre çalışma zamanında gerçekleşmeyecektir E .In this case the compile-time type of the assignment expression is dynamic, and the resolution described below will take place at run-time based on the run-time type of E.

Formun bir işlemi, x op= y işlem yazıldığı gibi ikili işleç aşırı yükleme çözümlemesi (ikili işleç aşırı yükleme çözümlemesi) uygulanarak işlenir x op y .An operation of the form x op= y is processed by applying binary operator overload resolution (Binary operator overload resolution) as if the operation was written x op y. NiThen,

  • Seçili işlecin dönüş türü örtük olarak türüne dönüştürülebilir ise, x işlem olarak değerlendirilir x = x op y , ancak x yalnızca bir kez değerlendirilir.If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
  • Aksi takdirde, seçilen işleç önceden tanımlanmış bir işleçse, seçili işlecin dönüş türü açık olarak türüne dönüştürülebilir x ve y türüne örtülü olarak dönüştürülebilir ise, x işlem x = (T)(x op y) yalnızca bir T x x kez değerlendirilse, türü olduğu gibi, bu, olarak değerlendirilir.Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.
  • Aksi takdirde, bileşik atama geçersizdir ve bir bağlama zamanı hatası oluşur.Otherwise, the compound assignment is invalid, and a binding-time error occurs.

"Yalnızca bir kez değerlendirilir" terimi x op y , ' nin, herhangi bir bileşen ifadesinin sonuçlarının x geçici olarak kaydedildiği ve atamayı gerçekleştirirken tekrar kullanıldığı anlamına gelir x .The term "evaluated only once" means that in the evaluation of x op y, the results of any constituent expressions of x are temporarily saved and then reused when performing the assignment to x. Örneğin, atamasında,, A()[B()] += C() A ve döndüren yöntemler ise, int[] B C int Yöntemler yalnızca bir kez, sırasıyla çağrılır A B C .For example, in the assignment A()[B()] += C(), where A is a method returning int[], and B and C are methods returning int, the methods are invoked only once, in the order A, B, C.

Bileşik atamanın sol işleneni bir özellik erişimi veya Dizin Oluşturucu erişimi olduğunda, özelliğin veya dizin oluşturucunun hem erişimcisi hem de get set erişimcisi olmalıdır.When the left operand of a compound assignment is a property access or indexer access, the property or indexer must have both a get accessor and a set accessor. Bu durumda, bir bağlama zamanı hatası oluşur.If this is not the case, a binding-time error occurs.

Yukarıdaki ikinci kural, x op= y belirli bağlamlarda olduğu gibi değerlendirilmesine izin verir x = (T)(x op y) .The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. Kural, sol işlenen,,, veya türünde olduğunda, önceden tanımlanmış işleçlerin Bileşik işleçler olarak kullanılabilmesi için vardır sbyte byte short ushort char .The rule exists such that the predefined operators can be used as compound operators when the left operand is of type sbyte, byte, short, ushort, or char. Her iki bağımsız değişken de bu türlerden birinde olsa da, önceden tanımlanmış işleçler, int ikili sayısal promosyonlarbölümünde açıklandığı gibi türünün bir sonucunu üretir.Even when both arguments are of one of those types, the predefined operators produce a result of type int, as described in Binary numeric promotions. Bu nedenle, bir dönüştürme olmadan sonucu sol işlenene atamak mümkün olmaz.Thus, without a cast it would not be possible to assign the result to the left operand.

Kuralın önceden tanımlanmış işleçleri için sezgisel etkisi yalnızca, x op= y x op y ve için x = y izin verildiğinde izin verilir.The intuitive effect of the rule for predefined operators is simply that x op= y is permitted if both of x op y and x = y are permitted. ÖrnekteIn the example

byte b = 0;
char ch = '\0';
int i = 0;

b += 1;             // Ok
b += 1000;          // Error, b = 1000 not permitted
b += i;             // Error, b = i not permitted
b += (byte)i;       // Ok

ch += 1;            // Error, ch = 1 not permitted
ch += (char)1;      // Ok

her hatanın sezgisel olmasının nedeni, karşılık gelen basit atamanın de hata olması olabilir.the intuitive reason for each error is that a corresponding simple assignment would also have been an error.

Bu ayrıca bileşik atama işlemlerinin yükseltilmemiş işlemlerini desteklediği anlamına gelir.This also means that compound assignment operations support lifted operations. ÖrnekteIn the example

int? i = 0;
i += 1;             // Ok

yükseltilmemiş işleci +(int?,int?) kullanılır.the lifted operator +(int?,int?) is used.

Olay atamasıEvent assignment

Bir += veya işlecinin sol işleneni -= bir olay erişimi olarak sınıflandırıldığında, ifade aşağıdaki gibi değerlendirilir:If the left operand of a += or -= operator is classified as an event access, then the expression is evaluated as follows:

  • Olay erişiminin, varsa örnek ifadesi değerlendirilir.The instance expression, if any, of the event access is evaluated.
  • +=OR işlecinin sağ işleneni -= değerlendirilir ve gerekirse, örtük bir dönüştürme (örtük dönüştürmeler) aracılığıyla Sol işlenen türüne dönüştürülür.The right operand of the += or -= operator is evaluated, and, if required, converted to the type of the left operand through an implicit conversion (Implicit conversions).
  • Etkinliğin olay erişimcisi, değerlendirmeden sonra ve gerekirse dönüştürme işlemi tamamlandıktan sonra bağımsız değişken listesiyle çağrılır.An event accessor of the event is invoked, with argument list consisting of the right operand, after evaluation and, if necessary, conversion. İşleç ise += add erişimci çağrılır; işleç ise -= remove erişimci çağrılır.If the operator was +=, the add accessor is invoked; if the operator was -=, the remove accessor is invoked.

Olay atama ifadesi bir değer vermez.An event assignment expression does not yield a value. Bu nedenle, bir olay atama ifadesi yalnızca bir statement_expression (ifade deyimleri) bağlamında geçerlidir.Thus, an event assignment expression is valid only in the context of a statement_expression (Expression statements).

ExpressionExpression

Bir ifade non_assignment_expression veya atamadır.An expression is either a non_assignment_expression or an assignment.

expression
    : non_assignment_expression
    | assignment
    ;

non_assignment_expression
    : conditional_expression
    | lambda_expression
    | query_expression
    ;

Sabit ifadelerConstant expressions

Constant_expression , derleme zamanında tam olarak değerlendirilebilen bir ifadedir.A constant_expression is an expression that can be fully evaluated at compile-time.

constant_expression
    : expression
    ;

Sabit bir ifade, null Şu türlerden birine sahip veya bir değer olmalıdır: sbyte , byte ,, short ushort , int , uint , long , ulong , char , float , double , decimal ,, bool , object string ,,,,,,,,, veya herhangi bir numaralandırma türü.A constant expression must be the null literal or a value with one of the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, object, string, or any enumeration type. Sabit ifadelerde yalnızca aşağıdaki yapılara izin verilir:Only the following constructs are permitted in constant expressions:

  • Sabit değerler ( null değişmez değer dahil).Literals (including the null literal).
  • constSınıf ve yapı türlerinin üyelerine başvurular.References to const members of class and struct types.
  • Numaralandırma türlerinin üyelerine başvurular.References to members of enumeration types.
  • constParametrelere veya yerel değişkenlere başvurularReferences to const parameters or local variables
  • Kendi sabit ifadeleri olan parantezli alt ifadeler.Parenthesized sub-expressions, which are themselves constant expressions.
  • Hedef türü yukarıda listelenen türlerden biri olarak verilen atama ifadeleri.Cast expressions, provided the target type is one of the types listed above.
  • checked ve unchecked ifadelerichecked and unchecked expressions
  • Varsayılan değer ifadeleriDefault value expressions
  • NameOf ifadeleriNameof expressions
  • Önceden tanımlanmış + , - , ! ve ~ Birli İşleçler.The predefined +, -, !, and ~ unary operators.
  • Ön tanımlı,,,,,,,,,,,,,,,,,,,,,,,,, + - * / % << >> & | ^ && || == != < > <= ve >= ikili işleçleri, her işlenen yukarıda listelenen bir tür.The predefined +, -, *, /, %, <<, >>, &, |, ^, &&, ||, ==, !=, <, >, <=, and >= binary operators, provided each operand is of a type listed above.
  • ?:Koşullu işleç.The ?: conditional operator.

Sabit ifadelerde aşağıdaki Dönüştürmelere izin verilir:The following conversions are permitted in constant expressions:

  • Kimlik dönüştürmeleriIdentity conversions
  • Sayısal DönüşümlerNumeric conversions
  • Sabit Listesi dönüştürmeleriEnumeration conversions
  • Sabit ifade dönüştürmeleriConstant expression conversions
  • Örtük ve açık başvuru dönüştürmeleri, dönüştürmelerin kaynağı null değeri değerlendiren sabit bir ifadedir.Implicit and explicit reference conversions, provided that the source of the conversions is a constant expression that evaluates to the null value.

Null olmayan değerlerin kutulamayı, kutudan çıkarma ve örtük başvuru dönüştürmelerine dahil diğer dönüştürmeler sabit ifadelerde kullanılamaz.Other conversions including boxing, unboxing and implicit reference conversions of non-null values are not permitted in constant expressions. Örnek:For example:

class C {
    const object i = 5;         // error: boxing conversion not permitted
    const object str = "hello"; // error: implicit reference conversion
}

bir paketleme dönüştürmesi gerektiğinden, ı başlatması bir hatadır.the initialization of i is an error because a boxing conversion is required. Null olmayan bir değerden örtük bir başvuru dönüştürmesi gerektiğinden Str başlatma bir hatadır.The initialization of str is an error because an implicit reference conversion from a non-null value is required.

Bir ifade yukarıda listelenen gereksinimleri karşılaışında, ifade derleme zamanında değerlendirilir.Whenever an expression fulfills the requirements listed above, the expression is evaluated at compile-time. Bu, ifade sabit olmayan yapılar içeren daha büyük bir ifadenin alt ifadesi olsa da geçerlidir.This is true even if the expression is a sub-expression of a larger expression that contains non-constant constructs.

Sabit ifadelerin derleme zamanı değerlendirmesi, sabit olmayan ifadelerin çalışma zamanı değerlendirmesiyle aynı kuralları kullanır, ancak çalışma zamanı değerlendirmesinin bir özel durum oluşturması, derleme zamanı değerlendirmesinin de bir derleme zamanı hatası oluşmasına neden olması gerekir.The compile-time evaluation of constant expressions uses the same rules as run-time evaluation of non-constant expressions, except that where run-time evaluation would have thrown an exception, compile-time evaluation causes a compile-time error to occur.

Sabit bir ifade açıkça bir bağlam içine yerleştirilmediği unchecked için, ifadenin derleme zamanı değerlendirmesi sırasında integral türü aritmetik işlemlerde ve dönüştürmelerde oluşan taşmalar her zaman derleme zamanı hatalarına neden olur (sabit ifadeler).Unless a constant expression is explicitly placed in an unchecked context, overflows that occur in integral-type arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors (Constant expressions).

Sabit ifadeler aşağıda listelenen bağlamlarda oluşur.Constant expressions occur in the contexts listed below. Bu bağlamlarda, bir ifade derleme zamanında tam olarak değerlendirilemez bir derleme zamanı hatası oluşur.In these contexts, a compile-time error occurs if an expression cannot be fully evaluated at compile-time.

Örtük bir sabit ifade dönüştürmesi (örtük sabit ifade dönüştürmeleri), türünde sabit bir ifadenin,,,, int veya olarak dönüştürülmesine izin verir sbyte byte short ushort uint ulong , ancak sabit ifadenin değeri hedef türünün aralığı içindedir.An implicit constant expression conversion (Implicit constant expression conversions) permits a constant expression of type int to be converted to sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant expression is within the range of the destination type.

Mantıksal ifadelerBoolean expressions

Boolean_expression , bool doğrudan veya operator true belirli bağlamlarda, aşağıda belirtildiği gibi, ' ın bir sonucu oluşturan bir ifadedir.A boolean_expression is an expression that yields a result of type bool; either directly or through application of operator true in certain contexts as specified in the following.

boolean_expression
    : expression
    ;

Bir if_statement (IF deyimi), while_statement (whiledeyimi), do_statement (Do deyimi) veya for_statement (for deyimi) denetim koşullu ifadesi bir Boolean_expression.The controlling conditional expression of an if_statement (The if statement), while_statement (The while statement), do_statement (The do statement), or for_statement (The for statement) is a boolean_expression. İşlecin koşullu ifadesi ?: (koşullu operatör), Boolean_expression aynı kurallara uyar, ancak işleç önceliğin nedenleri bir conditional_or_expression olarak sınıflandırıldı.The controlling conditional expression of the ?: operator (Conditional operator) follows the same rules as a boolean_expression, but for reasons of operator precedence is classified as a conditional_or_expression.

Bir Boolean_expression E , aşağıdaki gibi bir değer üretebilmek için gereklidir bool :A boolean_expression E is required to be able to produce a value of type bool, as follows:

  • Örtülü E olarak bool dönüştürme uygulandığında çalışma zamanında örtülü olarak dönüştürülebilir.If E is implicitly convertible to bool then at runtime that implicit conversion is applied.
  • Aksi halde, bir tekil operatör aşırı yükleme çözümü (birli operatör aşırı yükleme çözünürlüğü), üzerinde en iyi bir işleç uygulamasını bulmak için kullanılır true E ve bu uygulama çalışma zamanında uygulanır.Otherwise, unary operator overload resolution (Unary operator overload resolution) is used to find a unique best implementation of operator true on E, and that implementation is applied at runtime.
  • Böyle bir işleç bulunmazsa, bir bağlama zamanı hatası oluşur.If no such operator is found, a binding-time error occurs.

DBBool Veritabanı Boolean türündeki yapı türü, ve uygulayan bir türe örnek sağlar operator true operator false .The DBBool struct type in Database boolean type provides an example of a type that implements operator true and operator false.