DönüşümlerConversions

*Conversion _ bir ifadenin belirli bir türde olduğu kabul edilebilir olmasını sağlar.A *conversion _ enables an expression to be treated as being of a particular type. Bir dönüştürme, belirli bir türün ifadesinin farklı bir tür varmış gibi işlenmesine neden olabilir veya tür olmayan bir ifadenin tür almasını sağlayabilir.A conversion may cause an expression of a given type to be treated as having a different type, or it may cause an expression without a type to get a type. Dönüştürmeler *örtük* veya _ explicit * olabilir ve bu, açık bir dönüştürmenin gerekli olup olmadığını belirler.Conversions can be implicit or _*explicit**, and this determines whether an explicit cast is required. Örneğin, türünden int türüne dönüştürme long örtük olduğundan, türündeki ifadeler int örtülü olarak tür olarak kabul edilebilir long .For instance, the conversion from type int to type long is implicit, so expressions of type int can implicitly be treated as type long. Türünden türüne ters dönüştürme açıktır long int ve bu nedenle açık bir atama gerekir.The opposite conversion, from type long to type int, is explicit and so an explicit cast is required.

int a = 123;
long b = a;         // implicit conversion from int to long
int c = (int) b;    // explicit conversion from long to int

Bazı dönüşümler dil tarafından tanımlanır.Some conversions are defined by the language. Programlar, kendi dönüştürmelerini (Kullanıcı tanımlı dönüştürmeler) de tanımlayabilir.Programs may also define their own conversions (User-defined conversions).

Örtük dönüştürmelerImplicit conversions

Aşağıdaki dönüşümler örtük dönüştürmeler olarak sınıflandırılmaktadır:The following conversions are classified as implicit conversions:

  • Kimlik dönüştürmeleriIdentity conversions
  • Örtük Sayısal dönüştürmelerImplicit numeric conversions
  • Örtük numaralandırma dönüştürmeleriImplicit enumeration conversions
  • Örtülü olarak bulunan dize dönüşümleriImplicit interpolated string conversions
  • Örtük null yapılabilir dönüşümlerImplicit nullable conversions
  • Null değişmez değer dönüştürmeleriNull literal conversions
  • Örtük başvuru dönüştürmeleriImplicit reference conversions
  • Paketleme dönüştürmeleriBoxing conversions
  • Örtük dinamik dönüştürmelerImplicit dynamic conversions
  • Örtük sabit ifade dönüştürmeleriImplicit constant expression conversions
  • Kullanıcı tanımlı örtük dönüştürmelerUser-defined implicit conversions
  • Anonim işlev dönüştürmeleriAnonymous function conversions
  • Yöntem grubu dönüştürmeleriMethod group conversions

Örtük dönüştürmeler işlev üyesi etkinleştirmeleri (dinamik aşırı yükleme çözümünün derleme zamanı denetimi), atama Ifadeleri (atama işleçleri) veatamalar (atama işleçleri) dahil olmak üzere çeşitli durumlarda gerçekleşebilir.Implicit conversions can occur in a variety of situations, including function member invocations (Compile-time checking of dynamic overload resolution), cast expressions (Cast expressions), and assignments (Assignment operators).

Önceden tanımlanmış örtük dönüştürmeler her zaman başarılı olur ve hiçbir zaman özel durum oluşturulmasına neden olmaz.The pre-defined implicit conversions always succeed and never cause exceptions to be thrown. Doğru şekilde tasarlanan Kullanıcı tanımlı örtük dönüştürmeler bu özellikleri de göstermelidir.Properly designed user-defined implicit conversions should exhibit these characteristics as well.

Dönüştürme amaçları doğrultusunda türler object ve dynamic eşdeğer olarak kabul edilir.For the purposes of conversion, the types object and dynamic are considered equivalent.

Ancak dinamik dönüştürmeler (örtük dinamik dönüştürmeler ve Açık dinamik dönüştürmeler) yalnızca türündeki ifadeler için geçerlidir dynamic (dinamik tür).However, dynamic conversions (Implicit dynamic conversions and Explicit dynamic conversions) apply only to expressions of type dynamic (The dynamic type).

Kimlik dönüştürmeIdentity conversion

Bir kimlik dönüştürmesi herhangi bir türden aynı türe dönüştürür.An identity conversion converts from any type to the same type. Bu dönüştürme, zaten gerekli bir türü olan bir varlığın bu türe dönüştürülebilir olduğunu söylebilmelidir.This conversion exists such that an entity that already has a required type can be said to be convertible to that type.

  • objectVe dynamic eşdeğer olarak kabul edildiğinden, ile arasında bir kimlik dönüştürmesi object ve dynamic ile tüm oluşumları değiştirilirken aynı olan oluşturulmuş türler arasında dynamic object .Because object and dynamic are considered equivalent there is an identity conversion between object and dynamic, and between constructed types that are the same when replacing all occurrences of dynamic with object.

Örtük Sayısal dönüştürmelerImplicit numeric conversions

Örtük Sayısal dönüştürmeler şunlardır:The implicit numeric conversions are:

  • Sürümünden,,,, sbyte short int long float double , veya decimal .From sbyte to short, int, long, float, double, or decimal.
  • Sürümünden,,,,,, byte short ushort int uint long ulong float , double , veya decimal .From byte to short, ushort, int, uint, long, ulong, float, double, or decimal.
  • ,,,, short int Veya sürümünden long float double decimal .From short to int, long, float, double, or decimal.
  • Sürümünden,,,,, ushort int uint long ulong float double , veya decimal .From ushort to int, uint, long, ulong, float, double, or decimal.
  • Sürümünden int long ,, float double veya decimal .From int to long, float, double, or decimal.
  • ,,,, uint long Veya sürümünden ulong float double decimal .From uint to long, ulong, float, double, or decimal.
  • Sürümünden long float , double veya decimal .From long to float, double, or decimal.
  • Sürümünden ulong float , double veya decimal .From ulong to float, double, or decimal.
  • Sürümünden,,,,,, char ushort int uint long ulong float double veya decimal .From char to ushort, int, uint, long, ulong, float, double, or decimal.
  • Kaynağından float double .From float to double.

,, int uint long , Veya türünden ulong ve, float veya ile arasında dönüşümler long ulong double duyarlık kaybına neden olabilir, ancak hiçbir şekilde bir büyüklük kaybına neden olmaz.Conversions from int, uint, long, or ulong to float and from long or ulong to double may cause a loss of precision, but will never cause a loss of magnitude. Diğer örtük sayısal dönüştürmeler hiçbir bilgiyi hiçbir şekilde kaybetmez.The other implicit numeric conversions never lose any information.

Türe örtük dönüştürmeler yoktur char , bu nedenle diğer integral türlerin değerleri otomatik olarak türe dönüştürümez char .There are no implicit conversions to the char type, so values of the other integral types do not automatically convert to the char type.

Örtük numaralandırma dönüştürmeleriImplicit enumeration conversions

Örtük bir numaralandırma dönüştürmesi, decimal_integer_literal 0 herhangi bir enum_type ve temel alınan türü enum_type olan herhangi bir nullable_type dönüştürülmesine izin verir.An implicit enumeration conversion permits the decimal_integer_literal 0 to be converted to any enum_type and to any nullable_type whose underlying type is an enum_type. İkinci durumda, dönüştürme temel enum_type dönüştürülürken değerlendirilir ve sonuç (null yapılabilir türler) sarmalanacaktır.In the latter case the conversion is evaluated by converting to the underlying enum_type and wrapping the result (Nullable types).

Örtülü olarak bulunan dize dönüşümleriImplicit interpolated string conversions

Örtük bir enterpolasyonlu dize dönüştürme interpolated_string_expression (enterpolasyonlu dizeler) ' a System.IFormattable veya System.FormattableString (uygulayan) biçimine izin verir System.IFormattable .An implicit interpolated string conversion permits an interpolated_string_expression (Interpolated strings) to be converted to System.IFormattable or System.FormattableString (which implements System.IFormattable).

Bu dönüştürme uygulandığında, bir dize değeri, enterpolasyonlu dizeden oluşamaz.When this conversion is applied a string value is not composed from the interpolated string. Bunun yerine, bir örneği System.FormattableString , enterpolasyonlu dizelerdeaçıklanacak şekilde oluşturulur.Instead an instance of System.FormattableString is created, as further described in Interpolated strings.

Örtük null yapılabilir dönüşümlerImplicit nullable conversions

Null olamayan değer türlerinde çalışan önceden tanımlanmış örtük dönüştürmeler, bu türlerin null atanabilir formlarıyla de kullanılabilir.Predefined implicit conversions that operate on non-nullable value types can also be used with nullable forms of those types. Önceden tanımlı örtük kimlik ve sayısal dönüşümlerden her biri için, null yapılamayan bir değer türünden S null değer atanabilir olmayan bir değer türüne dönüştürme için T aşağıdaki örtük null yapılabilir dönüşümler mevcuttur:For each of the predefined implicit identity and numeric conversions that convert from a non-nullable value type S to a non-nullable value type T, the following implicit nullable conversions exist:

  • ' Den ' a örtük dönüşüm S? T? .An implicit conversion from S? to T?.
  • ' Den ' a örtük dönüşüm S T? .An implicit conversion from S to T?.

' Den başlayarak, temel alınan dönüştürmeye göre örtük olarak null yapılabilir dönüştürme değerlendirmesi S T :Evaluation of an implicit nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • Null yapılabilir dönüştürme şu şekilde olursa S? T? :If the nullable conversion is from S? to T?:

    • Kaynak değeri null ise ( HasValue özellik false ise) sonuç, türünün null değeridir T? .If the source value is null (HasValue property is false), the result is the null value of type T?.
    • Aksi takdirde, dönüştürme öğesinden öğesine geri sarılı olarak değerlendirilir ve öğesinden öğesine doğru dönüştürme ve öğesinden öğesine S? S S T bir sarmalama (null yapılabilir türler) gelir T T? .Otherwise, the conversion is evaluated as an unwrapping from S? to S, followed by the underlying conversion from S to T, followed by a wrapping (Nullable types) from T to T?.
  • Null yapılabilir dönüştürme S T? ' den ' a ise, dönüştürme, temel dönüşümü, öğesinden S T öğesine bir sarmalama tarafından izlenir olarak değerlendirilir T T? .If the nullable conversion is from S to T?, the conversion is evaluated as the underlying conversion from S to T followed by a wrapping from T to T?.

Null değişmez değer dönüştürmeleriNull literal conversions

nullDeğişmez değer, herhangi bir boş değer atanabilir türe sahiptir.An implicit conversion exists from the null literal to any nullable type. Bu dönüştürme, belirtilen null yapılabilir türdeki null değeri (null yapılabilir türler) oluşturur.This conversion produces the null value (Nullable types) of the given nullable type.

Örtük başvuru dönüştürmeleriImplicit reference conversions

Örtük başvuru dönüştürmeleri şunlardır:The implicit reference conversions are:

  • Reference_type object dynamic .From any reference_type to object and dynamic.
  • Herhangi bir class_type herhangi bir S class_type T , belirtilen ' S dan türetilir T .From any class_type S to any class_type T, provided S is derived from T.
  • Herhangi bir class_type S , tarafından interface_type T S uygulanır T .From any class_type S to any interface_type T, provided S implements T.
  • Herhangi bir interface_type herhangi bir S interface_type T , belirtilen ' S dan türetilir T .From any interface_type S to any interface_type T, provided S is derived from T.
  • S Öğe türü olan bir array_type SE T , öğe türü olan bir array_type için TE , aşağıdakilerin tümü doğru olarak belirtilmelidir:From an array_type S with an element type SE to an array_type T with an element type TE, provided all of the following are true:
    • S ve T yalnızca öğe türünde farklılık gösterir.S and T differ only in element type. Diğer bir deyişle, S T aynı sayıda boyuta sahiptir.In other words, S and T have the same number of dimensions.
    • Her ikisi de SE TE reference_type s.Both SE and TE are reference_type s.
    • Öğesinden öğesine örtük bir başvuru dönüştürmesi SE vardır TE .An implicit reference conversion exists from SE to TE.
  • Tüm array_type System.Array ve uyguladığı arabirimlere.From any array_type to System.Array and the interfaces it implements.
  • Tek boyutlu bir dizi türünden S[] System.Collections.Generic.IList<T> ve temel arayüzlerinden, ' den ' ye örtük bir kimlik veya başvuru dönüştürmesi olması şartıyla S T .From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces, provided that there is an implicit identity or reference conversion from S to T.
  • Tüm delegate_type System.Delegate ve uyguladığı arabirimlere.From any delegate_type to System.Delegate and the interfaces it implements.
  • Null değişmez değerinden herhangi bir reference_type.From the null literal to any reference_type.
  • Herhangi bir reference_type , bir T reference_type örtülü bir kimlik veya başvuru dönüştürmesi varsa T0 ve T0 öğesine bir kimlik dönüştürmesi varsa reference_type T .From any reference_type to a reference_type T if it has an implicit identity or reference conversion to a reference_type T0 and T0 has an identity conversion to T.
  • Herhangi bir reference_type , bir arabirim veya T temsilci türüne dönüştürülebilir bir kimlik ya da başvuru dönüştürmesi varsa T0 ve T0 değişken dönüşümtür ise (varyans dönüştürme) T .From any reference_type to an interface or delegate type T if it has an implicit identity or reference conversion to an interface or delegate type T0 and T0 is variance-convertible (Variance conversion) to T.
  • Başvuru türleri olarak bilinen tür parametreleri içeren örtük dönüştürmeler.Implicit conversions involving type parameters that are known to be reference types. Tür parametreleri içeren örtük dönüştürmeler hakkında daha fazla ayrıntı için bkz. tür parametreleri Içeren örtük dönüştürmeler .See Implicit conversions involving type parameters for more details on implicit conversions involving type parameters.

Örtük başvuru dönüştürmeleri, her zaman başarılı olarak kanıtlanmış reference_type s arasındaki Dönüştürmelere sahiptir ve bu nedenle çalışma zamanında hiçbir denetim gerektirmez.The implicit reference conversions are those conversions between reference_type s that can be proven to always succeed, and therefore require no checks at run-time.

Başvuru dönüştürmeleri, örtük veya açık, dönüştürülmekte olan nesnenin başvuru kimliğini hiçbir şekilde değiştirmeyin.Reference conversions, implicit or explicit, never change the referential identity of the object being converted. Diğer bir deyişle, bir başvuru dönüştürmesi başvurunun türünü değiştiremeken, başvuruda bulunulan nesnenin türünü veya değerini hiçbir şekilde değiştirmez.In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.

Paketleme dönüştürmeleriBoxing conversions

Kutulama dönüştürme bir value_type örtülü olarak bir başvuru türüne dönüştürülmesine izin verir.A boxing conversion permits a value_type to be implicitly converted to a reference type. Herhangi bir non_nullable_value_type object dynamic , System.ValueType non_nullable_value_type tarafından uygulanan interface_type ve arasında bir paketleme dönüştürmesi vardır.A boxing conversion exists from any non_nullable_value_type to object and dynamic, to System.ValueType and to any interface_type implemented by the non_nullable_value_type. Ayrıca bir enum_type türüne dönüştürülebilir System.Enum .Furthermore an enum_type can be converted to the type System.Enum.

Bir nullable_type bir referans türüne, yalnızca temeldeki non_nullable_value_type başvuru türüne bir paketleme dönüştürmesi varsa, bir paketleme dönüştürmesi vardır.A boxing conversion exists from a nullable_type to a reference type, if and only if a boxing conversion exists from the underlying non_nullable_value_type to the reference type.

Bir değer türünün bir arabirim I türüne paketleme dönüştürmesi varsa I0 ve bir I0 kimlik dönüştürmesi varsa, bir arabirim türüne kutulama dönüştürmesi vardır I .A value type has a boxing conversion to an interface type I if it has a boxing conversion to an interface type I0 and I0 has an identity conversion to I.

Bir değer türünün, bir arabirim I veya temsilci türüne paketleme dönüştürmesi varsa I0 ve I0 değişim dönüştürülebilir (varyans dönüştürmesi), bir arabirim türüne kutulama dönüştürmesi vardır I .A value type has a boxing conversion to an interface type I if it has a boxing conversion to an interface or delegate type I0 and I0 is variance-convertible (Variance conversion) to I.

Bir non_nullable_value_type değerini kutulama bir nesne örneği ayırmayı ve value_type değerini bu örneğe kopyalamayı içerir.Boxing a value of a non_nullable_value_type consists of allocating an object instance and copying the value_type value into that instance. Bir yapı, System.ValueType tüm yapılar (Devralma) için bir temel sınıf olduğundan, bu tür için kutulanabilir.A struct can be boxed to the type System.ValueType, since that is a base class for all structs (Inheritance).

Bir nullable_type değerini kutulama aşağıdaki gibi devam eder:Boxing a value of a nullable_type proceeds as follows:

  • Kaynak değeri null ise ( HasValue özellik false ise) sonuç, hedef türün null başvurusudur.If the source value is null (HasValue property is false), the result is a null reference of the target type.
  • Aksi takdirde sonuç, T kaynak değer sarmalanmış ve paketleme tarafından oluşturulan paketlenmiş bir başvurudur.Otherwise, the result is a reference to a boxed T produced by unwrapping and boxing the source value.

Paketleme dönüştürmeleri, paketleme dönüştürmelerindedaha ayrıntılı bir şekilde açıklanmıştır.Boxing conversions are described further in Boxing conversions.

Örtük dinamik dönüştürmelerImplicit dynamic conversions

Türü bir ifadeden herhangi bir türe örtük dinamik dönüştürme vardır dynamic T .An implicit dynamic conversion exists from an expression of type dynamic to any type T. Dönüştürme dinamik olarak bağlı (dinamik bağlama), yani örtük bir dönüştürme, ifadenin çalışma zamanı türünden çalışma zamanında bir şekilde alınacaktır T .The conversion is dynamically bound (Dynamic binding), which means that an implicit conversion will be sought at run-time from the run-time type of the expression to T. Dönüştürme bulunamazsa, bir çalışma zamanı özel durumu oluşturulur.If no conversion is found, a run-time exception is thrown.

Örtülü dönüştürmenin, örtük dönüştürmelerin başlangıcında asla bir özel duruma neden olmaması gerektiğine ilişkin önerileri ihlal ettiğini unutmayın.Note that this implicit conversion seemingly violates the advice in the beginning of Implicit conversions that an implicit conversion should never cause an exception. Ancak dönüştürmenin kendisi değil, özel duruma neden olan dönüştürmenin bulunması değildir.However it is not the conversion itself, but the finding of the conversion that causes the exception. Çalışma zamanı özel durumlarının riski dinamik bağlama kullanımına sahiptir.The risk of run-time exceptions is inherent in the use of dynamic binding. Dönüştürmenin dinamik bağlaması istenmiyorsa, ifade önce object ve ardından istenen türe dönüştürülebilir.If dynamic binding of the conversion is not desired, the expression can be first converted to object, and then to the desired type.

Aşağıdaki örnekte örtük dinamik dönüştürmeler gösterilmektedir:The following example illustrates implicit dynamic conversions:

object o  = "object"
dynamic d = "dynamic";

string s1 = o; // Fails at compile-time -- no conversion exists
string s2 = d; // Compiles and succeeds at run-time
int i     = d; // Compiles but fails at run-time -- no conversion exists

s2Ve i her ikisi de, işlemler bağlamasının çalışma zamanına kadar askıya alındığı örtük dinamik dönüştürmeler için ve her ikisi de kullanılır.The assignments to s2 and i both employ implicit dynamic conversions, where the binding of the operations is suspended until run-time. Çalışma zamanında örtük dönüştürmeler, ' ın çalışma zamanı türünden d -- string hedef türüne göre yapılır.At run-time, implicit conversions are sought from the run-time type of d -- string -- to the target type. Bir dönüştürme olarak bulunur, string ancak değil int .A conversion is found to string but not to int.

Örtük sabit ifade dönüştürmeleriImplicit constant expression conversions

Örtük bir sabit ifade dönüştürmesi aşağıdaki Dönüştürmelere izin verir:An implicit constant expression conversion permits the following conversions:

  • Türündeki bir constant_expression (sabit ifadeler),,,, int veya türüne sbyte dönüştürülebilir byte short ushort uint ulong , ancak constant_expression değeri hedef türünün aralığı içinde.A constant_expression (Constant expressions) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant_expression is within the range of the destination type.
  • Türün bir constant_expression long türüne dönüştürülebilir, ancak ulong constant_expression değeri negatif değil.A constant_expression of type long can be converted to type ulong, provided the value of the constant_expression is not negative.

Tür parametreleri içeren örtük dönüştürmelerImplicit conversions involving type parameters

Belirli bir tür parametresi için aşağıdaki örtük dönüştürmeler mevcuttur T :The following implicit conversions exist for a given type parameter T:

  • ' Dan T C T herhangi bir temel sınıfına C ve T tarafından uygulanan arayüze C kadar, etkin taban sınıfına.From T to its effective base class C, from T to any base class of C, and from T to any interface implemented by C. Çalışma zamanında, T bir değer türü ise, dönüştürme paketleme dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as a boxing conversion. Aksi takdirde, dönüştürme örtük bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • ' Dan T I , ' T nin etkin arabirim kümesine ve ' T nin herhangi bir temel arabirimine kadar olan bir arabirim türüne I .From T to an interface type I in T's effective interface set and from T to any base interface of I. Çalışma zamanında, T bir değer türü ise, dönüştürme paketleme dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as a boxing conversion. Aksi takdirde, dönüştürme örtük bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • Kaynağından T bir tür parametresine U , T U (tür parametresi kısıtlamalarına) bağlıdır.From T to a type parameter U, provided T depends on U (Type parameter constraints). Çalışma zamanında, U bir değer türü ise, T ve U aynı türde ve hiçbir dönüştürme gerçekleştirilmeyebilir.At run-time, if U is a value type, then T and U are necessarily the same type and no conversion is performed. Aksi takdirde, T bir değer türü ise, dönüştürme paketleme dönüştürmesi olarak yürütülür.Otherwise, if T is a value type, the conversion is executed as a boxing conversion. Aksi takdirde, dönüştürme örtük bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.
  • Null değişmez değerinden öğesine T ,, belirtilen T bir başvuru türü olarak bilinir.From the null literal to T, provided T is known to be a reference type.
  • Bir T I başvuru türüne örtülü dönüştürmeye sahip S0 ve S0 öğesine bir kimlik dönüştürmesi varsa, öğesinden başvuru türüne S .From T to a reference type I if it has an implicit conversion to a reference type S0 and S0 has an identity conversion to S. Çalışma zamanında dönüştürme işlemi ile aynı şekilde yürütülür S0 .At run-time the conversion is executed the same way as the conversion to S0.
  • Bir T I arabirim veya temsilci türüne örtülü dönüştürmeye sahip olan I0 ve I0 varyans I (varyans dönüştürmesi) ise, bir arabirim türüne öğesinden.From T to an interface type I if it has an implicit conversion to an interface or delegate type I0 and I0 is variance-convertible to I (Variance conversion). Çalışma zamanında, T bir değer türü ise, dönüştürme paketleme dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as a boxing conversion. Aksi takdirde, dönüştürme örtük bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an implicit reference conversion or identity conversion.

TBir başvuru türü (tür parametresi kısıtlamaları) olarak bilindiğinde, yukarıdaki dönüşümler tamamen örtük başvuru dönüştürmeleri (örtük başvuru dönüştürmeleri) olarak sınıflandırılır.If T is known to be a reference type (Type parameter constraints), the conversions above are all classified as implicit reference conversions (Implicit reference conversions). TBir başvuru türü olarak bilinmiyorsa, yukarıdaki dönüştürmeler paketleme dönüştürmeleri (kutulama dönüştürmeleri) olarak sınıflandırılmaktadır.If T is not known to be a reference type, the conversions above are classified as boxing conversions (Boxing conversions).

Kullanıcı tanımlı örtük dönüştürmelerUser-defined implicit conversions

Kullanıcı tanımlı örtük dönüştürme, isteğe bağlı standart bir örtük dönüştürme, ardından Kullanıcı tanımlı örtük dönüştürme işlecinin yürütülmesi ve ardından isteğe bağlı bir standart örtük dönüştürme ile oluşur.A user-defined implicit conversion consists of an optional standard implicit conversion, followed by execution of a user-defined implicit conversion operator, followed by another optional standard implicit conversion. Kullanıcı tanımlı örtük dönüştürmeleri değerlendirmek için tam kurallar, Kullanıcı tanımlı örtük dönüştürmelerin işlenmesindeaçıklanmıştır.The exact rules for evaluating user-defined implicit conversions are described in Processing of user-defined implicit conversions.

Anonim işlev dönüştürmeleri ve Yöntem grubu dönüştürmeleriAnonymous function conversions and method group conversions

Anonim işlevler ve yöntem grupları, ve içinde türlerine sahip değildir, ancak dolaylı olarak temsilci türlerine veya ifade ağaç türlerine dönüştürülebilir.Anonymous functions and method groups do not have types in and of themselves, but may be implicitly converted to delegate types or expression tree types. Anonim işlev dönüştürmeleri, metot grubu dönüştürmelerinde Adsız işlev dönüştürmelerinde ve Yöntem grubu dönüştürmelerinde daha ayrıntılı bir şekilde açıklanmıştır.Anonymous function conversions are described in more detail in Anonymous function conversions and method group conversions in Method group conversions.

Açık dönüşümlerExplicit conversions

Aşağıdaki dönüşümler açık dönüştürmeler olarak sınıflandırılmaktadır:The following conversions are classified as explicit conversions:

  • Tüm örtük dönüştürmeler.All implicit conversions.
  • Açık sayısal dönüştürmeler.Explicit numeric conversions.
  • Açık sabit listesi dönüştürmeleri.Explicit enumeration conversions.
  • Açık boş değer atanabilir dönüşümler.Explicit nullable conversions.
  • Açık başvuru dönüştürmeleri.Explicit reference conversions.
  • Açık arabirim dönüştürmeleri.Explicit interface conversions.
  • Kutudan çıkarma dönüştürmeleri.Unboxing conversions.
  • Açık dinamik dönüştürmelerExplicit dynamic conversions
  • Kullanıcı tanımlı açık dönüştürmeler.User-defined explicit conversions.

Dönüştürme ifadelerinde açık dönüştürmeler oluşabilir (atama ifadeleri).Explicit conversions can occur in cast expressions (Cast expressions).

Açık dönüştürmeler kümesi tüm örtük dönüştürmeleri içerir.The set of explicit conversions includes all implicit conversions. Bu, gereksiz atama ifadelerine izin verilen anlamına gelir.This means that redundant cast expressions are allowed.

Örtük dönüştürmeler olmayan açık dönüştürmeler, her zaman başarılı olmak üzere kendini kanıtlanamaz dönüşümlerdir, bilinen dönüştürmeler, büyük olasılıkla bilgi kaybedecektir ve türlerin etki alanları arasında dönüştürmeleri geniştir açık gösterimine kadar farklıdır.The explicit conversions that are not implicit conversions are conversions that cannot be proven to always succeed, conversions that are known to possibly lose information, and conversions across domains of types sufficiently different to merit explicit notation.

Açık sayısal dönüştürmelerExplicit numeric conversions

Açık sayısal dönüştürmeler, bir numeric_type örtük bir sayısal dönüştürmenin (örtük sayısal dönüştürmeler) zaten mevcut olmadığı başka bir numeric_type dönüşümlerdir:The explicit numeric conversions are the conversions from a numeric_type to another numeric_type for which an implicit numeric conversion (Implicit numeric conversions) does not already exist:

  • ,,,, sbyte byte Veya sürümünden ushort uint ulong char .From sbyte to byte, ushort, uint, ulong, or char.
  • İle byte sbyte ve arasında char .From byte to sbyte and char.
  • Sürümünden,,,, short sbyte byte ushort uint ulong , veya char .From short to sbyte, byte, ushort, uint, ulong, or char.
  • Sürümünden ushort sbyte ,, byte short veya char .From ushort to sbyte, byte, short, or char.
  • Sürümünden,,,,, int sbyte byte short ushort uint ulong , veya char .From int to sbyte, byte, short, ushort, uint, ulong, or char.
  • Sürümünden,,,, uint sbyte byte short ushort int , veya char .From uint to sbyte, byte, short, ushort, int, or char.
  • Sürümünden,,,,,, long sbyte byte short ushort int uint ulong veya char .From long to sbyte, byte, short, ushort, int, uint, ulong, or char.
  • Sürümünden,,,,,, ulong sbyte byte short ushort int uint long veya char .From ulong to sbyte, byte, short, ushort, int, uint, long, or char.
  • Sürümünden char sbyte , byte veya short .From char to sbyte, byte, or short.
  • Sürümünden,,,,,, float sbyte byte short ushort int uint long , ulong ,, char veya decimal .From float to sbyte, byte, short, ushort, int, uint, long, ulong, char, or decimal.
  • Sürümünden,,,,,, double sbyte byte short ushort int uint long , ulong ,, char , float veya decimal .From double to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or decimal.
  • Sürümünden,,,,,, decimal sbyte byte short ushort int uint long , ulong ,, char , float veya double .From decimal to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double.

Açık dönüştürmeler tüm örtük ve açık sayısal dönüştürmeleri içerdiğinden, herhangi bir numeric_type bir atama Ifadesi (atama ifadeleri) kullanarak herhangi bir numeric_type başka bir dönüştürmek her zaman mümkündür.Because the explicit conversions include all implicit and explicit numeric conversions, it is always possible to convert from any numeric_type to any other numeric_type using a cast expression (Cast expressions).

Açık sayısal dönüştürmeler büyük olasılıkla bilgileri kaybedebilir veya büyük olasılıkla özel durumların oluşturulmasına neden olabilir.The explicit numeric conversions possibly lose information or possibly cause exceptions to be thrown. Açık bir sayısal dönüştürme şu şekilde işlenir:An explicit numeric conversion is processed as follows:

  • İntegral türünden başka bir integral türüne dönüştürme işlemi için işleme, dönüştürmenin gerçekleştiği taşma Denetim bağlamına (denetlenen ve işaretlenmemiş operatörler) bağlıdır:For a conversion from an integral type to another integral type, the processing depends on the overflow checking context (The checked and unchecked operators) in which the conversion takes place:
    • Bir checked bağlamda, kaynak işlenenin değeri hedef türü Aralık içindeyse dönüştürme başarılı olur, ancak System.OverflowException kaynak işlenenin değeri hedef türü aralığının dışındaysa bir atar.In a checked context, the conversion succeeds if the value of the source operand is within the range of the destination type, but throws a System.OverflowException if the value of the source operand is outside the range of the destination type.
    • Bir unchecked bağlamda, dönüştürme her zaman başarılı olur ve aşağıdaki gibi devam eder.In an unchecked context, the conversion always succeeds, and proceeds as follows.
      • Kaynak türü hedef türünden büyükse, "ekstra" en önemli bitleri atarak kaynak değer kesilir.If the source type is larger than the destination type, then the source value is truncated by discarding its "extra" most significant bits. Sonuç daha sonra hedef türünün bir değeri olarak değerlendirilir.The result is then treated as a value of the destination type.
      • Kaynak türü hedef türünden küçükse, hedef türle aynı boyutta olması için, kaynak değeri ya imza veya sıfır genişletilmiş ya da sıfır genişletilmiş olur.If the source type is smaller than the destination type, then the source value is either sign-extended or zero-extended so that it is the same size as the destination type. Kaynak türü imzalanmışsa, oturum açma uzantısı kullanılır; Kaynak türü işaretsiz ise sıfır uzantı kullanılır.Sign-extension is used if the source type is signed; zero-extension is used if the source type is unsigned. Sonuç daha sonra hedef türünün bir değeri olarak değerlendirilir.The result is then treated as a value of the destination type.
      • Kaynak türü hedef türle aynı boyutta ise, kaynak değer hedef türün bir değeri olarak değerlendirilir.If the source type is the same size as the destination type, then the source value is treated as a value of the destination type.
  • Bir decimal integral türüne dönüştürme için, kaynak değer en yakın tamsayı değerine sıfır doğru yuvarlanır ve bu tam sayı değeri dönüştürmenin sonucu olur.For a conversion from decimal to an integral type, the source value is rounded towards zero to the nearest integral value, and this integral value becomes the result of the conversion. Elde edilen integral değeri, hedef türü aralığının dışındaysa, bir System.OverflowException atılır.If the resulting integral value is outside the range of the destination type, a System.OverflowException is thrown.
  • floatYa da double bir integral türüne dönüştürme için, işleme, dönüştürmenin gerçekleştiği taşma Denetim bağlamına (denetlenen ve işaretlenmemiş operatörler) bağlıdır:For a conversion from float or double to an integral type, the processing depends on the overflow checking context (The checked and unchecked operators) in which the conversion takes place:
    • Bir checked bağlamda, dönüştürme aşağıdaki gibi devam eder:In a checked context, the conversion proceeds as follows:
      • İşlenenin değeri NaN veya sonsuz ise, bir System.OverflowException atılır.If the value of the operand is NaN or infinite, a System.OverflowException is thrown.
      • Aksi takdirde, kaynak işleneni en yakın tamsayı değerine sıfır doğru yuvarlanır.Otherwise, the source operand is rounded towards zero to the nearest integral value. Bu integral değeri hedef türünün aralığı içindeyse, bu değer dönüştürmenin sonucudur.If this integral value is within the range of the destination type then this value is the result of the conversion.
      • Aksi takdirde, bir System.OverflowException oluşturulur.Otherwise, a System.OverflowException is thrown.
    • Bir unchecked bağlamda, dönüştürme her zaman başarılı olur ve aşağıdaki gibi devam eder.In an unchecked context, the conversion always succeeds, and proceeds as follows.
      • İşlenenin değeri NaN veya sonsuz ise, dönüştürmenin sonucu hedef türün belirtilmemiş bir değeridir.If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type.
      • Aksi takdirde, kaynak işleneni en yakın tamsayı değerine sıfır doğru yuvarlanır.Otherwise, the source operand is rounded towards zero to the nearest integral value. Bu integral değeri hedef türünün aralığı içindeyse, bu değer dönüştürmenin sonucudur.If this integral value is within the range of the destination type then this value is the result of the conversion.
      • Aksi takdirde, dönüştürmenin sonucu hedef türün belirtilmemiş bir değeridir.Otherwise, the result of the conversion is an unspecified value of the destination type.
  • ' Dan ' a dönüştürme için double float , double değer en yakın float değere yuvarlanır.For a conversion from double to float, the double value is rounded to the nearest float value. doubleDeğer bir olarak temsil edemeyecek kadar küçükse float , sonuç pozitif sıfır veya negatif sıfır olur.If the double value is too small to represent as a float, the result becomes positive zero or negative zero. doubleDeğer bir olarak temsil etmek için çok büyükse float , sonuç pozitif sonsuzluk veya negatif sonsuzluk olur.If the double value is too large to represent as a float, the result becomes positive infinity or negative infinity. doubleDeğer NaN ise, sonuç de NaN olur.If the double value is NaN, the result is also NaN.
  • Veya ' den bir dönüştürme için float double decimal , kaynak değer decimal gösterimine dönüştürülür ve gerekirse, 28 ondalık konumundan sonra en yakın sayıya yuvarlanır (ondalık türü).For a conversion from float or double to decimal, the source value is converted to decimal representation and rounded to the nearest number after the 28th decimal place if required (The decimal type). Kaynak değeri, olarak temsil edilebilmesi için çok küçük ise decimal , sonuç sıfır olur.If the source value is too small to represent as a decimal, the result becomes zero. Kaynak değeri NaN, Infinity veya olarak temsil edilebilmesi için çok büyükse decimal , bir System.OverflowException atılır.If the source value is NaN, infinity, or too large to represent as a decimal, a System.OverflowException is thrown.
  • Veya ' den ' a dönüştürme için decimal float double , decimal değer en yakın double veya float değere yuvarlanır.For a conversion from decimal to float or double, the decimal value is rounded to the nearest double or float value. Bu dönüştürme duyarlığı kaybedebilir, ancak hiçbir durum özel durum oluşturulmasına neden olmaz.While this conversion may lose precision, it never causes an exception to be thrown.

Açık sabit listesi dönüştürmeleriExplicit enumeration conversions

Açık numaralandırma dönüştürmeleri şunlardır:The explicit enumeration conversions are:

  • ,,,,,,, sbyte byte short ushort int uint long ulong , char , float , double , Ya da decimal herhangi bir enum_type.From sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, or decimal to any enum_type.
  • Herhangi bir enum_type ,,,,,,,, sbyte byte short ushort int uint long ulong char , float , double , veya decimal .From any enum_type to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, or decimal.
  • Herhangi bir enum_type başka bir enum_type.From any enum_type to any other enum_type.

İki tür arasında açık bir sabit listesi dönüştürme işlemi, herhangi bir katılım enum_type , bu enum_type temel alınan türü olarak davranarak işlenir ve ardından sonuçtaki türler arasında örtük veya açık bir sayısal dönüştürme gerçekleştirerek.An explicit enumeration conversion between two types is processed by treating any participating enum_type as the underlying type of that enum_type, and then performing an implicit or explicit numeric conversion between the resulting types. Örneğin, E ve temel türü enum_type verildiğinde int , öğesinden öğesine dönüştürme, ' dan ' a bir E byte Açık sayısal dönüştürme (Açık sayısal dönüştürmeler) olarak işlenir int byte ve öğesinden öğesine dönüştürme örtük bir byte E sayısal dönüştürme (örtük sayısal dönüştürmeler) olarak ' den ' a bir olarak işlenir byte int .For example, given an enum_type E with and underlying type of int, a conversion from E to byte is processed as an explicit numeric conversion (Explicit numeric conversions) from int to byte, and a conversion from byte to E is processed as an implicit numeric conversion (Implicit numeric conversions) from byte to int.

Açık boş değer atanabilir dönüşümlerExplicit nullable conversions

Açık null yapılabilir dönüşümler , null olamayan değer türlerinde çalışan önceden tanımlı açık Dönüştürmelere izin verir ve bu türlerin null yapılabilir formlarıyla de kullanılır.Explicit nullable conversions permit predefined explicit conversions that operate on non-nullable value types to also be used with nullable forms of those types. Null yapılamayan bir değer türünden S null olamaz değer türüne T (kimlik dönüştürme, örtük sayısal dönüştürmeler, örtük numaralandırma dönüştürmeleri, Açık sayısal dönüştürmelerve Açık sabit listesi dönüştürmeleri) dönüştüren önceden tanımlanmış açık dönüştürmeler için, aşağıdaki null yapılabilir dönüşümler mevcuttur:For each of the predefined explicit conversions that convert from a non-nullable value type S to a non-nullable value type T (Identity conversion, Implicit numeric conversions, Implicit enumeration conversions, Explicit numeric conversions, and Explicit enumeration conversions), the following nullable conversions exist:

  • Öğesinden öğesine açık bir S? dönüştürme T? .An explicit conversion from S? to T?.
  • Öğesinden öğesine açık bir S dönüştürme T? .An explicit conversion from S to T?.
  • Öğesinden öğesine açık bir S? dönüştürme T .An explicit conversion from S? to T.

' Den itibaren temel alınan dönüştürmeye göre null yapılabilir dönüştürme değerlendirmesi S T aşağıdaki gibi devam eder:Evaluation of a nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • Null yapılabilir dönüştürme şu şekilde olursa S? T? :If the nullable conversion is from S? to T?:
    • Kaynak değeri null ise ( HasValue özellik false ise) sonuç, türünün null değeridir T? .If the source value is null (HasValue property is false), the result is the null value of type T?.
    • Aksi takdirde, dönüştürme ' dan ' a bir sarmalama olarak değerlendirilir ve ardından ' den S? S ' dan S T ' a bir sarmalama tarafından izlenir T T? .Otherwise, the conversion is evaluated as an unwrapping from S? to S, followed by the underlying conversion from S to T, followed by a wrapping from T to T?.
  • Null yapılabilir dönüştürme S T? ' den ' a ise, dönüştürme, temel dönüşümü, öğesinden S T öğesine bir sarmalama tarafından izlenir olarak değerlendirilir T T? .If the nullable conversion is from S to T?, the conversion is evaluated as the underlying conversion from S to T followed by a wrapping from T to T?.
  • Null yapılabilir dönüştürme ' den ' a ise S? T , dönüştürme, ' den ' dan ' a bir sarmalama olarak değerlendirilir S? S S T .If the nullable conversion is from S? to T, the conversion is evaluated as an unwrapping from S? to S followed by the underlying conversion from S to T.

Null yapılabilir bir değeri sarmalama denemesinin değeri ise bir özel durum oluşturur null .Note that an attempt to unwrap a nullable value will throw an exception if the value is null.

Açık başvuru dönüştürmeleriExplicit reference conversions

Açık başvuru dönüştürmeleri şunlardır:The explicit reference conversions are:

  • objectVe dynamic diğer reference_type.From object and dynamic to any other reference_type.
  • Herhangi bir class_type herhangi S bir class_type T , belirtilen S temel bir sınıftır T .From any class_type S to any class_type T, provided S is a base class of T.
  • Herhangi bir class_type herhangi bir S interface_type T , S korumalı değildir ve sağlanmamıştır S T .From any class_type S to any interface_type T, provided S is not sealed and provided S does not implement T.
  • Herhangi bir interface_type herhangi bir S class_type T , T korumalı veya sağlanmış bir T uygulamadır S .From any interface_type S to any class_type T, provided T is not sealed or provided T implements S.
  • Herhangi bir interface_type herhangi bir S interface_type T , belirtilen ' S dan türetilmez T .From any interface_type S to any interface_type T, provided S is not derived from T.
  • S Öğe türü olan bir array_type SE T , öğe türü olan bir array_type için TE , aşağıdakilerin tümü doğru olarak belirtilmelidir:From an array_type S with an element type SE to an array_type T with an element type TE, provided all of the following are true:
    • S ve T yalnızca öğe türünde farklılık gösterir.S and T differ only in element type. Diğer bir deyişle, S T aynı sayıda boyuta sahiptir.In other words, S and T have the same number of dimensions.
    • Her ikisi de SE TE reference_type s.Both SE and TE are reference_type s.
    • ' Dan ' a açık bir başvuru dönüştürmesi vardır SE TE .An explicit reference conversion exists from SE to TE.
  • System.ArrayVe tarafından herhangi bir array_type uyguladığı arabirimler.From System.Array and the interfaces it implements to any array_type.
  • Tek boyutlu dizi türünden S[] System.Collections.Generic.IList<T> ve temel arabirimlerine, ' den ' e açık bir başvuru dönüştürmesi olması şartıyla S T .From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces, provided that there is an explicit reference conversion from S to T.
  • Kaynağından System.Collections.Generic.IList<S> ve temel arabirimlerinden T[] , ' den açık bir kimlik veya başvuru dönüştürmesi olması şartıyla, tek boyutlu bir dizi türüne S T .From System.Collections.Generic.IList<S> and its base interfaces to a single-dimensional array type T[], provided that there is an explicit identity or reference conversion from S to T.
  • System.DelegateVe tarafından herhangi bir delegate_type uyguladığı arabirimler.From System.Delegate and the interfaces it implements to any delegate_type.
  • Bir başvuru türüne T açık başvuru dönüştürmesi varsa T0 ve bir T0 kimlik dönüştürmesi varsa başvuru türünden başvuru türüne T .From a reference type to a reference type T if it has an explicit reference conversion to a reference type T0 and T0 has an identity conversion T.
  • Bir arabirim veya temsilci türüne açık başvuru dönüştürmesi varsa ve bir başvuru türünden bir arabirime ya da temsilci türüne, T T0 T0 fark-dönüştürülebilir ya da varyans T T -dönüştürülebilir T0 (varyans dönüştürmesi).From a reference type to an interface or delegate type T if it has an explicit reference conversion to an interface or delegate type T0 and either T0 is variance-convertible to T or T is variance-convertible to T0 (Variance conversion).
  • , ' Den D<S1...Sn> D<T1...Tn> /' D<X1...Xn> a genel bir temsilci türü, D<S1...Sn> ile uyumlu değildir D<T1...Tn> ve Xi aşağıdaki ayrı her bir tür parametresi için D :From D<S1...Sn> to D<T1...Tn> where D<X1...Xn> is a generic delegate type, D<S1...Sn> is not compatible with or identical to D<T1...Tn>, and for each type parameter Xi of D the following holds:
    • XiSabit ise, Si ile aynıdır Ti .If Xi is invariant, then Si is identical to Ti.
    • XiBirlikte değişken ise, öğesinden bir örtük veya açık kimlik veya başvuru dönüştürmesi vardır Si Ti .If Xi is covariant, then there is an implicit or explicit identity or reference conversion from Si to Ti.
    • Değişken Xi karşıtı ise, Si ve Ti her ikisi de özdeş veya her ikisi başvuru türüdür.If Xi is contravariant, then Si and Ti are either identical or both reference types.
  • Başvuru türleri olarak bilinen tür parametreleri içeren açık dönüştürmeler.Explicit conversions involving type parameters that are known to be reference types. Tür parametreleriyle ilgili açık dönüştürmeler hakkında daha fazla ayrıntı için bkz. tür parametreleri Içeren açık dönüştürmeler.For more details on explicit conversions involving type parameters, see Explicit conversions involving type parameters.

Açık başvuru dönüştürmeleri, doğru olduklarından emin olmak için çalışma zamanı denetimleri gerektiren başvuru türleri arasındaki dönüşümlerdir.The explicit reference conversions are those conversions between reference-types that require run-time checks to ensure they are correct.

Açık bir başvuru dönüştürmenin çalışma zamanında başarılı olması için, kaynak işlenenin değeri olmalıdır null veya kaynak işleneni tarafından başvurulan nesnenin gerçek türü, örtük bir başvuru dönüştürmesi (örtük başvuru dönüştürmeleri) veya paketleme dönüştürmesi (kutulama dönüştürmeleri) tarafından hedef türe dönüştürülebilen bir tür olmalıdır.For an explicit reference conversion to succeed at run-time, the value of the source operand must be null, or the actual type of the object referenced by the source operand must be a type that can be converted to the destination type by an implicit reference conversion (Implicit reference conversions) or boxing conversion (Boxing conversions). Açık bir başvuru dönüştürmesi başarısız olursa, bir System.InvalidCastException oluşturulur.If an explicit reference conversion fails, a System.InvalidCastException is thrown.

Başvuru dönüştürmeleri, örtük veya açık, dönüştürülmekte olan nesnenin başvuru kimliğini hiçbir şekilde değiştirmeyin.Reference conversions, implicit or explicit, never change the referential identity of the object being converted. Diğer bir deyişle, bir başvuru dönüştürmesi başvurunun türünü değiştiremeken, başvuruda bulunulan nesnenin türünü veya değerini hiçbir şekilde değiştirmez.In other words, while a reference conversion may change the type of the reference, it never changes the type or value of the object being referred to.

Kutudan çıkarma dönüştürmeleriUnboxing conversions

Kutudan çıkarma dönüştürmesi, bir başvuru türünün açıkça bir value_type dönüştürülmesine izin verir.An unboxing conversion permits a reference type to be explicitly converted to a value_type. Türlerden ve herhangi bir object non_nullable_value_type ve herhangi bir dynamic System.ValueType interface_type , interface_type uygulayan non_nullable_value_type için bir kutudan çıkarma dönüştürmesi vardır.An unboxing conversion exists from the types object, dynamic and System.ValueType to any non_nullable_value_type, and from any interface_type to any non_nullable_value_type that implements the interface_type. Ayrıca tür System.Enum herhangi bir enum_type kutulanabilir.Furthermore type System.Enum can be unboxed to any enum_type.

Başvuru türünden nullable_type temel non_nullable_value_type bir kutudan çıkarma dönüştürmesi varsa, bir başvuru türünden bir paket açma dönüştürmesi nullable_type vardır.An unboxing conversion exists from a reference type to a nullable_type if an unboxing conversion exists from the reference type to the underlying non_nullable_value_type of the nullable_type.

Bir değer türünün bir arabirim S I türünden kutudan çıkarma dönüştürmesi varsa I0 ve I0 öğesine bir kimlik dönüştürmesi varsa, bir arabirim türünden kutudan çıkarma dönüştürmesi vardır I .A value type S has an unboxing conversion from an interface type I if it has an unboxing conversion from an interface type I0 and I0 has an identity conversion to I.

Bir değer türünün, S bir arabirim veya temsilci türünden bir paket açma dönüştürmesi varsa I I0 ve I0 varyans-dönüştürülebilir ya da varyans I I -dönüştürülebilir değerine I0 (varyans dönüştürme) sahip bir arabirim türünden bir kutudan çıkarma dönüştürmesi vardır.A value type S has an unboxing conversion from an interface type I if it has an unboxing conversion from an interface or delegate type I0 and either I0 is variance-convertible to I or I is variance-convertible to I0 (Variance conversion).

Kutudan çıkarma işlemi, nesne örneğinin verilen value_type kutulanmış bir değer olup olmadığını kontrol ederek değeri örnekten dışarı kopyalamaktan oluşur.An unboxing operation consists of first checking that the object instance is a boxed value of the given value_type, and then copying the value out of the instance. Bir nullable_type null başvurusunun kutudan çıkarma nullable_type null değeri üretir.Unboxing a null reference to a nullable_type produces the null value of the nullable_type. Yapı, System.ValueType tüm yapılar (Devralma) için temel bir sınıf olduğundan, türden kutulanabilir.A struct can be unboxed from the type System.ValueType, since that is a base class for all structs (Inheritance).

Kutudan çıkarma dönüştürmeleri, kutudan çıkarma dönüştürmelerindeaçıklanacaktır.Unboxing conversions are described further in Unboxing conversions.

Açık dinamik dönüştürmelerExplicit dynamic conversions

Türü bir ifadeden herhangi bir türe açık dinamik dönüştürme vardır dynamic T .An explicit dynamic conversion exists from an expression of type dynamic to any type T. Dönüştürme dinamik olarak bağlı (dinamik bağlama), yani açık bir dönüştürme, ifadenin çalışma zamanı türünden çalışma zamanında bir şekilde alınacaktır T .The conversion is dynamically bound (Dynamic binding), which means that an explicit conversion will be sought at run-time from the run-time type of the expression to T. Dönüştürme bulunamazsa, bir çalışma zamanı özel durumu oluşturulur.If no conversion is found, a run-time exception is thrown.

Dönüştürmenin dinamik bağlaması istenmiyorsa, ifade önce object ve ardından istenen türe dönüştürülebilir.If dynamic binding of the conversion is not desired, the expression can be first converted to object, and then to the desired type.

Aşağıdaki sınıfın tanımlandığını varsayalım:Assume the following class is defined:

class C
{
    int i;

    public C(int i) { this.i = i; }

    public static explicit operator C(string s) 
    {
        return new C(int.Parse(s));
    }
}

Aşağıdaki örnekte açık dinamik dönüştürmeler gösterilmektedir:The following example illustrates explicit dynamic conversions:

object o  = "1";
dynamic d = "2";

var c1 = (C)o; // Compiles, but explicit reference conversion fails
var c2 = (C)d; // Compiles and user defined conversion succeeds

' In en iyi dönüşümü, o C derleme zamanında açık bir başvuru dönüştürmesi olacak şekilde bulunur.The best conversion of o to C is found at compile-time to be an explicit reference conversion. Bu, "1" aslýnda a içinde olmadığından, çalışma zamanında başarısız olur C .This fails at run-time, because "1" is not in fact a C. d C Ancak, açıkça bir dinamik dönüştürme olarak ' a dönüştürme işlemi, çalışma zamanı türünden ' a bir Kullanıcı tanımlı dönüştürme olduğu d -- string C ve başarılı olarak askıya alınır.The conversion of d to C however, as an explicit dynamic conversion, is suspended to run-time, where a user defined conversion from the run-time type of d -- string -- to C is found, and succeeds.

Tür parametreleri içeren açık dönüştürmelerExplicit conversions involving type parameters

Verilen tür parametresi için aşağıdaki açık dönüştürmeler mevcuttur T :The following explicit conversions exist for a given type parameter T:

  • Öğesinin etkin temel sınıfından C T T öğesine ve temel sınıfından öğesine C T .From the effective base class C of T to T and from any base class of C to T. Çalışma zamanında, T bir değer türü ise, dönüştürme bir kutudan çıkarma dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as an unboxing conversion. Aksi takdirde, dönüştürme açık bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • Herhangi bir arabirim türünden öğesine T .From any interface type to T. Çalışma zamanında, T bir değer türü ise, dönüştürme bir kutudan çıkarma dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as an unboxing conversion. Aksi takdirde, dönüştürme açık bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • ' Den T herhangi bir interface_type , ' den ' a I örtük bir dönüşüm T değildir I .From T to any interface_type I provided there is not already an implicit conversion from T to I. Çalışma zamanında, T bir değer türü ise, dönüştürme bir paketleme dönüştürmesi ve ardından açık bir başvuru dönüştürmesi olarak yürütülür.At run-time, if T is a value type, the conversion is executed as a boxing conversion followed by an explicit reference conversion. Aksi takdirde, dönüştürme açık bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.
  • Bir tür parametresinden U öğesine T göre, belirtilen T U (tür parametresi kısıtlamalarına) bağımlıdır.From a type parameter U to T, provided T depends on U (Type parameter constraints). Çalışma zamanında, U bir değer türü ise, T ve U aynı türde ve hiçbir dönüştürme gerçekleştirilmeyebilir.At run-time, if U is a value type, then T and U are necessarily the same type and no conversion is performed. Aksi takdirde, T bir değer türü ise, dönüştürme bir kutudan çıkarma dönüştürmesi olarak yürütülür.Otherwise, if T is a value type, the conversion is executed as an unboxing conversion. Aksi takdirde, dönüştürme açık bir başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.Otherwise, the conversion is executed as an explicit reference conversion or identity conversion.

TBir başvuru türü olarak bilindiğinde, yukarıdaki dönüşümler tamamen açık başvuru dönüştürmeleri (açık başvuru dönüştürmeleri) olarak sınıflandırılır.If T is known to be a reference type, the conversions above are all classified as explicit reference conversions (Explicit reference conversions). TBir başvuru türü olarak bilinmiyorsa, yukarıdaki dönüştürmeler kutudan çıkarma dönüştürmeleri (kutudan çıkarma dönüştürmeleri) olarak sınıflandırılır.If T is not known to be a reference type, the conversions above are classified as unboxing conversions (Unboxing conversions).

Yukarıdaki kurallar, kısıtlanmamış bir tür parametresinden doğrudan açık dönüştürmeye, arabirim olmayan bir türe izin vermez, bu da şaşırtıcı olabilir.The above rules do not permit a direct explicit conversion from an unconstrained type parameter to a non-interface type, which might be surprising. Bu kuralın nedeni karışıklığa engel olmak ve bu tür dönüştürmelerin semantiğini temizlemek için kullanılır.The reason for this rule is to prevent confusion and make the semantics of such conversions clear. Örneğin, aşağıdaki bildirimi ele alalım:For example, consider the following declaration:

class X<T>
{
    public static long F(T t) {
        return (long)t;                // Error 
    }
}

' A doğrudan açık dönüştürmeye t int izin verildiğinde, bir tane daha sonra X<int>.F(7) dönebilecek şekilde bekleyebilir  7L .If the direct explicit conversion of t to int were permitted, one might easily expect that X<int>.F(7) would return 7L. Ancak, Standart Sayısal Dönüşümler yalnızca türlerin bağlama sırasında sayısal olarak bilindiğinde kabul edildiği için değildir.However, it would not, because the standard numeric conversions are only considered when the types are known to be numeric at binding-time. Semantiğini açık hale getirmek için yukarıdaki örneğin yazılması gerekir:In order to make the semantics clear, the above example must instead be written:

class X<T>
{
    public static long F(T t) {
        return (long)(object)t;        // Ok, but will only work when T is long
    }
}

Bu kod artık derlenir X<int>.F(7) , ancak bir paketlenmiş bir int doğrudan bir öğesine dönüştürülemediğinden çalışma zamanında bir özel durum oluşturur long .This code will now compile but executing X<int>.F(7) would then throw an exception at run-time, since a boxed int cannot be converted directly to a long.

Kullanıcı tanımlı açık dönüşümlerUser-defined explicit conversions

Kullanıcı tanımlı açık dönüştürme, isteğe bağlı bir standart açık dönüşümden, ardından Kullanıcı tanımlı örtük veya açık bir dönüştürme işlecinin yürütülmesi ve ardından isteğe bağlı bir standart açık dönüştürme ile oluşur.A user-defined explicit conversion consists of an optional standard explicit conversion, followed by execution of a user-defined implicit or explicit conversion operator, followed by another optional standard explicit conversion. Kullanıcı tanımlı Açık dönüştürmeleri değerlendirmek için tam kurallar, Kullanıcı tanımlı açık dönüştürmelerin işlenmesindeaçıklanmıştır.The exact rules for evaluating user-defined explicit conversions are described in Processing of user-defined explicit conversions.

Standart dönüşümlerStandard conversions

Standart dönüştürmeler, Kullanıcı tanımlı dönüştürmenin bir parçası olarak gerçekleşebileceğini önceden tanımlanmış dönüşümlerdir.The standard conversions are those pre-defined conversions that can occur as part of a user-defined conversion.

Standart örtük dönüştürmelerStandard implicit conversions

Aşağıdaki örtük dönüştürmeler standart örtük dönüştürmeler olarak sınıflandırılmaktadır:The following implicit conversions are classified as standard implicit conversions:

Standart örtük dönüştürmeler özellikle Kullanıcı tanımlı örtük dönüştürmeleri hariç tutar.The standard implicit conversions specifically exclude user-defined implicit conversions.

Standart açık dönüşümlerStandard explicit conversions

Standart açık dönüştürmeler tüm standart örtük dönüştürmelerdir ve ters bir standart örtük dönüştürmenin bulunduğu açık dönüştürmelerin alt kümesidir.The standard explicit conversions are all standard implicit conversions plus the subset of the explicit conversions for which an opposite standard implicit conversion exists. Diğer bir deyişle, bir türden standart örtük dönüştürme bir türe varsa, türünden türüne ve türünden türüne A B Standart bir açık dönüştürme vardır A B B A .In other words, if a standard implicit conversion exists from a type A to a type B, then a standard explicit conversion exists from type A to type B and from type B to type A.

Kullanıcı tanımlı dönüştürmelerUser-defined conversions

C#, önceden tanımlanmış örtük ve açık dönüştürmelerin Kullanıcı tanımlı dönüşümlere göre artırılmasına izin verir.C# allows the pre-defined implicit and explicit conversions to be augmented by user-defined conversions. Kullanıcı tanımlı dönüştürmeler, sınıf ve yapı türlerinde dönüştürme işleçleri (dönüştürme işleçleri) bildirerek ortaya çıkartılır.User-defined conversions are introduced by declaring conversion operators (Conversion operators) in class and struct types.

İzin verilen Kullanıcı tanımlı dönüştürmelerPermitted user-defined conversions

C# yalnızca belirli kullanıcı tanımlı dönüştürmelerin bildirilmesine izin verir.C# permits only certain user-defined conversions to be declared. Özellikle, zaten varolan bir örtük veya açık dönüştürmeyi yeniden tanımlamak mümkün değildir.In particular, it is not possible to redefine an already existing implicit or explicit conversion.

Belirli bir kaynak türü S ve hedef türü için T , S T null yapılabilir türler varsa, S0 kendi temel türlerine izin verin ve bunlara T0 başvurur, aksi takdirde ve S0 T0 S sırasıyla eşittir T .For a given source type S and target type T, if S or T are nullable types, let S0 and T0 refer to their underlying types, otherwise S0 and T0 are equal to S and T respectively. Bir sınıf veya yapının, S T yalnızca aşağıdakilerin tümü doğru olduğunda bir kaynak türünden hedef türüne dönüştürme bildirmesine izin verilir:A class or struct is permitted to declare a conversion from a source type S to a target type T only if all of the following are true:

  • S0 ve T0 farklı türlerdir.S0 and T0 are different types.
  • S0Ya da T0 işleç bildiriminin gerçekleştiği sınıf veya yapı türüdür.Either S0 or T0 is the class or struct type in which the operator declaration takes place.
  • Ne S0 ne de T0 bir interface_type.Neither S0 nor T0 is an interface_type.
  • Kullanıcı tanımlı dönüştürmeler hariç olmak üzere dönüştürme, ' den ' e veya ' den ' a arasında bulunmaz S T T S .Excluding user-defined conversions, a conversion does not exist from S to T or from T to S.

Kullanıcı tanımlı dönüştürmeler için uygulanan kısıtlamalar, dönüştürme işleçlerindedaha ayrıntılı bir şekilde ele alınmıştır.The restrictions that apply to user-defined conversions are discussed further in Conversion operators.

Yükseltilmemiş dönüştürme işleçleriLifted conversion operators

Null yapılamayan bir değer türünden null yapılamayan değer türüne dönüştüren Kullanıcı tanımlı bir dönüştürme işleci verildiğinde S T , ' den ' a dönüştüren bir yükseltilmemiş dönüştürme işleci vardır S? T? .Given a user-defined conversion operator that converts from a non-nullable value type S to a non-nullable value type T, a lifted conversion operator exists that converts from S? to T?. Bu yükseltilmemiş dönüştürme işleci, öğesinden öğesinden S? S S T bir sarmalamadan sonra T , null değerli bir T? null değerli değere dönüştürülebilinerek, öğesinden öğesinden öğesinden bir kaydırmasını gerçekleştirir S? T? .This lifted conversion operator performs an unwrapping from S? to S followed by the user-defined conversion from S to T followed by a wrapping from T to T?, except that a null valued S? converts directly to a null valued T?.

Bir yükseltilmemiş dönüştürme işleci, temel aldığı Kullanıcı tanımlı dönüştürme işleci ile aynı örtük veya açık sınıflandırmasına sahiptir.A lifted conversion operator has the same implicit or explicit classification as its underlying user-defined conversion operator. "Kullanıcı tanımlı dönüştürme" terimi hem Kullanıcı tanımlı hem de yükseltilmemiş dönüştürme işleçlerinin kullanımı için geçerlidir.The term "user-defined conversion" applies to the use of both user-defined and lifted conversion operators.

Kullanıcı tanımlı dönüştürmeler değerlendirmesiEvaluation of user-defined conversions

Kullanıcı tanımlı dönüştürme, kaynak türü _ olarak adlandırılan türünden bir değeri, _hedef türü*_ olarak adlandırılan başka bir türe dönüştürür.A user-defined conversion converts a value from its type, called the source type _, to another type, called the _target type*_. Belirli bir kaynak ve hedef türleri için en belirgin* Kullanıcı tanımlı dönüştürme işlecini bulmaya yönelik kullanıcı tanımlı dönüştürme merkezlerinin değerlendirmesi.Evaluation of a user-defined conversion centers on finding the _ most specific* user-defined conversion operator for the particular source and target types. Bu belirleme birkaç adımda bozulur:This determination is broken into several steps:

  • Kullanıcı tanımlı dönüştürme işleçlerinin kabul edileceği sınıfların ve yapıların kümesini bulma.Finding the set of classes and structs from which user-defined conversion operators will be considered. Bu küme, kaynak türünden ve temel sınıflarından ve hedef türünden ve temel sınıflarından oluşur (yalnızca sınıfların ve yapıların Kullanıcı tanımlı işleçleri bildirebilme ve sınıf olmayan türlerin temel sınıfları olmadığı örtük varsayımlar ile).This set consists of the source type and its base classes and the target type and its base classes (with the implicit assumptions that only classes and structs can declare user-defined operators, and that non-class types have no base classes). Bu adımın amaçları doğrultusunda, kaynak veya hedef tür bir nullable_type ise bunun yerine temel alınan türü kullanılır.For the purposes of this step, if either the source or target type is a nullable_type, their underlying type is used instead.
  • Bu tür kümesinden, hangi kullanıcı tanımlı ve yükseltilmemiş dönüştürme işleçlerinin geçerli olduğunu belirlemek.From that set of types, determining which user-defined and lifted conversion operators are applicable. Bir dönüştürme işlecinin geçerli olması için, kaynak türünden işlecin işlenen türüne Standart dönüştürme (Standart dönüşümler) gerçekleştirmek mümkün olmalıdır ve işlecin sonuç türünden hedef türüne standart bir dönüştürme gerçekleştirmek mümkün olmalıdır.For a conversion operator to be applicable, it must be possible to perform a standard conversion (Standard conversions) from the source type to the operand type of the operator, and it must be possible to perform a standard conversion from the result type of the operator to the target type.
  • Geçerli Kullanıcı tanımlı işleçler kümesinden, hangi işlecin kesin olarak en belirgin olduğunu belirleme.From the set of applicable user-defined operators, determining which operator is unambiguously the most specific. Genel koşullarda, en özel işleç, işlenen türü kaynak türüne "en yakın" olan ve sonuç türü hedef türüne "en yakın" olan işleçtir.In general terms, the most specific operator is the operator whose operand type is "closest" to the source type and whose result type is "closest" to the target type. Kullanıcı tanımlı dönüştürme işleçleri yükseltilmemiş dönüştürme işleçleri üzerinden tercih edilir.User-defined conversion operators are preferred over lifted conversion operators. En belirli kullanıcı tanımlı dönüştürme işlecini oluşturmaya yönelik kuralların tam kuralları aşağıdaki bölümlerde tanımlanmıştır.The exact rules for establishing the most specific user-defined conversion operator are defined in the following sections.

En çok belirli bir Kullanıcı tanımlı dönüştürme işleci tanımlandıktan sonra, Kullanıcı tanımlı dönüştürmenin gerçek yürütmesi üç adımdan oluşur:Once a most specific user-defined conversion operator has been identified, the actual execution of the user-defined conversion involves up to three steps:

  • İlk olarak, gerekirse, kaynak türünden Kullanıcı tanımlı veya yükseltilmemiş dönüştürme işlecinin işlenen türüne standart bir dönüştürme işlemi gerçekleştiriliyor.First, if required, performing a standard conversion from the source type to the operand type of the user-defined or lifted conversion operator.
  • Sonra, dönüştürmeyi gerçekleştirmek için Kullanıcı tanımlı veya yükseltilmemiş dönüştürme işlecini çağırma.Next, invoking the user-defined or lifted conversion operator to perform the conversion.
  • Son olarak, gerekirse Kullanıcı tanımlı veya yükseltilmemiş dönüştürme işlecinin sonuç türünden hedef türüne standart bir dönüştürme işlemi gerçekleştiriliyor.Finally, if required, performing a standard conversion from the result type of the user-defined or lifted conversion operator to the target type.

Kullanıcı tanımlı bir dönüştürmenin değerlendirmesi hiçbir şekilde birden fazla Kullanıcı tanımlı veya yükseltilmemiş dönüştürme işleci içerir.Evaluation of a user-defined conversion never involves more than one user-defined or lifted conversion operator. Diğer bir deyişle, türünden türüne dönüştürme öncelikle ' dan ' a bir S T Kullanıcı tanımlı dönüştürme yürütmez ve ' S X den ' e Kullanıcı tanımlı bir dönüştürme yürütmeyecektir X T .In other words, a conversion from type S to type T will never first execute a user-defined conversion from S to X and then execute a user-defined conversion from X to T.

Aşağıdaki bölümlerde Kullanıcı tanımlı örtük veya açık dönüşümler değerlendirmesinin tam tanımları verilmiştir.Exact definitions of evaluation of user-defined implicit or explicit conversions are given in the following sections. Tanımlar aşağıdaki terimleri kullanır:The definitions make use of the following terms:

  • Bir türden standart örtük dönüştürme (Standart örtük dönüştürmeler) bir türden varsa A B ve ne A de B interface_type s yoksa, A _ tarafından dahil edilir B ve B _ ** * A .If a standard implicit conversion (Standard implicit conversions) exists from a type A to a type B, and if neither A nor B are interface_type s, then A is said to be encompassed by _ B, and B is said to _ encompass A.
  • Bir tür kümesindeki en kapsamlı tür , küme içindeki diğer tüm türleri kapsayan tek türdür.The most encompassing type in a set of types is the one type that encompasses all other types in the set. Tek bir tür diğer tüm türleri kapsadığı takdirde, küme en fazla kapsayan türe sahip değildir.If no single type encompasses all other types, then the set has no most encompassing type. Daha sezgisel koşullarda, en çok kapsayan tür, küme içindeki "en büyük" türdür — diğer türlerin her birinin örtük olarak dönüştürülebileceği bir tür.In more intuitive terms, the most encompassing type is the "largest" type in the set—the one type to which each of the other types can be implicitly converted.
  • Bir tür kümesindeki en kapsamlı tür , küme içindeki tüm diğer türler tarafından dahil edilen tek türdür.The most encompassed type in a set of types is the one type that is encompassed by all other types in the set. Tüm diğer türler tarafından tek bir tür yoksa, küme, en çok kullanılan türe sahip değildir.If no single type is encompassed by all other types, then the set has no most encompassed type. Daha sezgisel koşullarda, en kapsamlı tür, küme içindeki "en küçük" türüdür ve örtülü olarak diğer türlerin her birine dönüştürülebilirler.In more intuitive terms, the most encompassed type is the "smallest" type in the set—the one type that can be implicitly converted to each of the other types.

Kullanıcı tanımlı örtük dönüştürmeleri işlemeProcessing of user-defined implicit conversions

Tür türünden türüne Kullanıcı tanımlı örtük dönüştürme S T işlemi şu şekilde işlenir:A user-defined implicit conversion from type S to type T is processed as follows:

  • Türlerini ve türünü S0 saptayın T0 .Determine the types S0 and T0. SYa da T null yapılabilir türler varsa S0 ve T0 temel türleri ise, aksi takdirde S0 ve T0 S sırasıyla eşittir T .If S or T are nullable types, S0 and T0 are their underlying types, otherwise S0 and T0 are equal to S and T respectively.
  • DKullanıcı tanımlı dönüştürme işleçlerinin kabul edileceği tür kümesini bulun.Find the set of types, D, from which user-defined conversion operators will be considered. Bu küme, S0 (bir sınıf S0 veya yapı ise), temel sınıfları (Eğer bir sınıfsa) S0 S0 ve T0 ( T0 bir sınıf veya yapı ise) oluşur.This set consists of S0 (if S0 is a class or struct), the base classes of S0 (if S0 is a class), and T0 (if T0 is a class or struct).
  • Geçerli Kullanıcı tanımlı ve yükseltilmemiş dönüştürme işleçleri kümesini bulun U .Find the set of applicable user-defined and lifted conversion operators, U. Bu küme, ' de bulunan ve D tarafından dahil edilen bir türe dönüştüren bir türden dönüştürme içindeki sınıflar veya yapılar tarafından belirtilen kullanıcı tanımlı ve yükseltilmemiş örtük dönüştürme işleçlerinden oluşur S T .This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs in D that convert from a type encompassing S to a type encompassed by T. UBoşsa, dönüştürme tanımsızdır ve derleme zamanı hatası oluşur.If U is empty, the conversion is undefined and a compile-time error occurs.
  • İçindeki operatörlerin en belirli kaynak türünü bulun SX U :Find the most specific source type, SX, of the operators in U:
    • ' Deki işleçlerden herhangi biri U S , ' SX dır S .If any of the operators in U convert from S, then SX is S.
    • Aksi takdirde, SX içindeki operatörlerin Birleşik kaynak türleri kümesindeki en kapsamlı türdür U .Otherwise, SX is the most encompassed type in the combined set of source types of the operators in U. Tam olarak en kapsamlı bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If exactly one most encompassed type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • İçindeki operatörlerin en belirli hedef türünü bulun TX U :Find the most specific target type, TX, of the operators in U:
    • ' Deki işleçlerden herhangi biri U öğesine dönüşürsünüz T TX T .If any of the operators in U convert to T, then TX is T.
    • Aksi takdirde, TX içindeki operatörlerin birleştirilmiş hedef türleri kümesindeki en kapsamlı bir tür U .Otherwise, TX is the most encompassing type in the combined set of target types of the operators in U. Tam olarak en kapsamlı bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • En belirli dönüştürme işlecini bulun:Find the most specific conversion operator:
    • UYalnızca ' den ' a dönüştüren bir Kullanıcı tanımlı dönüştürme işleci içeriyorsa SX TX , bu, en özel dönüştürme işleçtir.If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • Aksi takdirde, ' U den ' a dönüştüren tek bir yükseltilmemiş dönüştürme işleci içeriyorsa SX TX , bu, en özel dönüştürme işleçtir.Otherwise, if U contains exactly one lifted conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • Aksi takdirde, dönüştürme belirsizdir ve bir derleme zamanı hatası oluşur.Otherwise, the conversion is ambiguous and a compile-time error occurs.
  • Son olarak, dönüştürmeyi uygulayın:Finally, apply the conversion:
    • Değilse S SX , öğesinden öğesine standart bir örtük dönüşüm S SX yapılır.If S is not SX, then a standard implicit conversion from S to SX is performed.
    • En belirgin dönüştürme işleci, ' dan ' a dönüştürülecek şekilde çağrılır SX TX .The most specific conversion operator is invoked to convert from SX to TX.
    • Değilse TX T , öğesinden öğesine standart bir örtük dönüşüm TX T yapılır.If TX is not T, then a standard implicit conversion from TX to T is performed.

Kullanıcı tanımlı Açık dönüştürmeleri işlemeProcessing of user-defined explicit conversions

Tür türünden türüne Kullanıcı tanımlı bir açık dönüştürme S T işlemi şu şekilde işlenir:A user-defined explicit conversion from type S to type T is processed as follows:

  • Türlerini ve türünü S0 saptayın T0 .Determine the types S0 and T0. SYa da T null yapılabilir türler varsa S0 ve T0 temel türleri ise, aksi takdirde S0 ve T0 S sırasıyla eşittir T .If S or T are nullable types, S0 and T0 are their underlying types, otherwise S0 and T0 are equal to S and T respectively.
  • DKullanıcı tanımlı dönüştürme işleçlerinin kabul edileceği tür kümesini bulun.Find the set of types, D, from which user-defined conversion operators will be considered. Bu küme, (bir sınıf veya yapı ise), (bir sınıf S0 S0 veya yapı ise) Taban sınıfları S0 S0 T0 T0 ve T0 (Eğer T0 bir sınıfsa) temel sınıfları ile oluşur.This set consists of S0 (if S0 is a class or struct), the base classes of S0 (if S0 is a class), T0 (if T0 is a class or struct), and the base classes of T0 (if T0 is a class).
  • Geçerli Kullanıcı tanımlı ve yükseltilmemiş dönüştürme işleçleri kümesini bulun U .Find the set of applicable user-defined and lifted conversion operators, U. Bu küme, Kullanıcı tanımlı ve yükseltilmemiş örtük ya da yapı tarafından tanımlanan, tarafından dahil edilen veya dahil edilen bir türe göre veya buna dahil edilen bir tür tarafından belirtilen bir tür veya yan yana dönüştürme işleçlerinden oluşur D S T .This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs in D that convert from a type encompassing or encompassed by S to a type encompassing or encompassed by T. UBoşsa, dönüştürme tanımsızdır ve derleme zamanı hatası oluşur.If U is empty, the conversion is undefined and a compile-time error occurs.
  • İçindeki operatörlerin en belirli kaynak türünü bulun SX U :Find the most specific source type, SX, of the operators in U:
    • ' Deki işleçlerden herhangi biri U S , ' SX dır S .If any of the operators in U convert from S, then SX is S.
    • Aksi takdirde, ' deki U işleçlerden herhangi biri, çevreleyen türlerden herhangi biri ise S , SX Bu operatörlerin birleştirilmiş kaynak türleri kümesindeki en kapsamlı türdür.Otherwise, if any of the operators in U convert from types that encompass S, then SX is the most encompassed type in the combined set of source types of those operators. En çok kullanılan tür bulunamıyorsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs.
    • Aksi takdirde, SX içindeki operatörlerin Birleşik kaynak türleri kümesindeki en kapsamlı bir tür U .Otherwise, SX is the most encompassing type in the combined set of source types of the operators in U. Tam olarak en kapsamlı bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
  • İçindeki operatörlerin en belirli hedef türünü bulun TX U :Find the most specific target type, TX, of the operators in U:
    • ' Deki işleçlerden herhangi biri U öğesine dönüşürsünüz T TX T .If any of the operators in U convert to T, then TX is T.
    • Aksi halde, içindeki işleçlerden herhangi biri U tarafından dahil edilen türlere dönüşütürse T , TX Bu operatörlerin birleştirilmiş hedef türleri kümesindeki en kapsamlı bir tür olur.Otherwise, if any of the operators in U convert to types that are encompassed by T, then TX is the most encompassing type in the combined set of target types of those operators. Tam olarak en kapsamlı bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If exactly one most encompassing type cannot be found, then the conversion is ambiguous and a compile-time error occurs.
    • Aksi takdirde, TX içindeki operatörlerin Birleşik hedef türleri kümesindeki en kapsamlı türdür U .Otherwise, TX is the most encompassed type in the combined set of target types of the operators in U. En çok kullanılan tür bulunamıyorsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.If no most encompassed type can be found, then the conversion is ambiguous and a compile-time error occurs.
  • En belirli dönüştürme işlecini bulun:Find the most specific conversion operator:
    • UYalnızca ' den ' a dönüştüren bir Kullanıcı tanımlı dönüştürme işleci içeriyorsa SX TX , bu, en özel dönüştürme işleçtir.If U contains exactly one user-defined conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • Aksi takdirde, ' U den ' a dönüştüren tek bir yükseltilmemiş dönüştürme işleci içeriyorsa SX TX , bu, en özel dönüştürme işleçtir.Otherwise, if U contains exactly one lifted conversion operator that converts from SX to TX, then this is the most specific conversion operator.
    • Aksi takdirde, dönüştürme belirsizdir ve bir derleme zamanı hatası oluşur.Otherwise, the conversion is ambiguous and a compile-time error occurs.
  • Son olarak, dönüştürmeyi uygulayın:Finally, apply the conversion:
    • Değilse S SX , öğesinden öğesine standart bir açık dönüştürme S SX gerçekleştirilir.If S is not SX, then a standard explicit conversion from S to SX is performed.
    • En belirgin Kullanıcı tanımlı dönüştürme işleci, ' dan ' a dönüştürmek için SX çağrılır TX .The most specific user-defined conversion operator is invoked to convert from SX to TX.
    • Değilse TX T , öğesinden öğesine standart bir açık dönüştürme TX T gerçekleştirilir.If TX is not T, then a standard explicit conversion from TX to T is performed.

Anonim işlev dönüştürmeleriAnonymous function conversions

Bir anonymous_method_expression veya lambda_expression anonim Işlev olarak sınıflandırılır (anonim işlev ifadeleri).An anonymous_method_expression or lambda_expression is classified as an anonymous function (Anonymous function expressions). İfade bir türe sahip değil, ancak örtülü olarak uyumlu bir temsilci türüne veya ifade ağacı türüne dönüştürülebilir.The expression does not have a type but can be implicitly converted to a compatible delegate type or expression tree type. Özellikle anonim bir işlev, F belirtilen bir temsilci türü ile uyumludur D :Specifically, an anonymous function F is compatible with a delegate type D provided:

  • FBir anonymous_function_signature içeriyorsa D ve F aynı sayıda parametreye sahip olmalıdır.If F contains an anonymous_function_signature, then D and F have the same number of parameters.
  • FBir anonymous_function_signature içermiyorsa, hiçbir D parametresi D out parametre değiştiricisine sahip olmadığı sürece herhangi bir türde sıfır veya daha fazla parametreye sahip olabilir.If F does not contain an anonymous_function_signature, then D may have zero or more parameters of any type, as long as no parameter of D has the out parameter modifier.
  • FAçıkça yazılmış bir parametre listesine sahipse, içindeki her bir parametre D içindeki karşılık gelen parametresiyle aynı tür ve değiştiricilere sahiptir F .If F has an explicitly typed parameter list, each parameter in D has the same type and modifiers as the corresponding parameter in F.
  • FÖrtük olarak yazılmış bir parametre listesine sahipse, D ref veya parametresi yoktur out .If F has an implicitly typed parameter list, D has no ref or out parameters.
  • Gövdesi F bir ifade ise ve D bir void dönüş türüne sahipse ya da F zaman uyumsuz ise ve D dönüş türüne sahipse Task , her parametresine F karşılık gelen parametresinin türü verildiğinde, D öğesinin gövdesi, F statement_expression (Ifade deyimleri) olarak izin verilen geçerli bir ifade (WRT ifadeleri) olur.If the body of F is an expression, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (wrt Expressions) that would be permitted as a statement_expression (Expression statements).
  • Gövdesi F bir deyim bloğu ise ve D bir void dönüş türüne sahipse ya da F zaman uyumsuz ise ve D dönüş türüne sahipse Task , öğesinin her parametresi F içinde karşılık gelen parametrenin türü verildiğinde D , öğesinin gövdesi, F hiçbir deyimin bir Ifadeyi belirttiği geçerli bir deyim bloğu (WRT blokları) olur return .If the body of F is a statement block, and either D has a void return type or F is async and D has the return type Task, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid statement block (wrt Blocks) in which no return statement specifies an expression.
  • Gövdesi F bir ifade ise ve bu, F zaman uyumsuz ve D void olmayan bir dönüş türüne sahipse T ya da F zaman uyumsuz ise ve D bir dönüş türüne sahipse, öğesinin Task<T> her parametresine F karşılık gelen parametresinin türü verildiğinde, D öğesinin gövdesi F örtük olarak dönüştürülebilir geçerli bir ifadedir (WRT ifadeleri) T .If the body of F is an expression, and either F is non-async and D has a non-void return type T, or F is async and D has a return type Task<T>, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid expression (wrt Expressions) that is implicitly convertible to T.
  • Gövdesi F bir ifade bloğu ise, F zaman uyumsuz ve D void olmayan bir dönüş türüne sahip T ya da F zaman uyumsuz ve D bir dönüş türüne sahip Task<T> , her bir parametre ' F de karşılık gelen parametrenin türü verildiğinde, D öğesinin gövdesi, F her return deyimin örtük olarak dönüştürülebilir bir ifadeyi belirttiği, erişilebilir olmayan bir uç noktası olan geçerli bir deyim bloğu (WRT blokları) T .If the body of F is a statement block, and either F is non-async and D has a non-void return type T, or F is async and D has a return type Task<T>, then when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid statement block (wrt Blocks) with a non-reachable end point in which each return statement specifies an expression that is implicitly convertible to T.

Bu bölümde, breçekimi amacıyla görev türleri Task ve Task<T> (zaman uyumsuz işlevler) için kısa form kullanılır.For the purpose of brevity, this section uses the short form for the task types Task and Task<T> (Async functions).

Bir lambda ifadesi, F Expression<D> F temsilci türüyle uyumluysa bir ifade ağacı türü ile uyumludur D .A lambda expression F is compatible with an expression tree type Expression<D> if F is compatible with the delegate type D. Bu, anonim metotlar için, yalnızca Lambda ifadelerinde uygulanmadığını unutmayın.Note that this does not apply to anonymous methods, only lambda expressions.

Bazı lambda ifadeleri ifade ağacı türlerine dönüştürülemez: dönüştürme mevcut olsa bile, derleme zamanında başarısız olur.Certain lambda expressions cannot be converted to expression tree types: Even though the conversion exists, it fails at compile-time. Lambda ifadesi ise bu durum budur:This is the case if the lambda expression:

  • Bir blok gövdesine sahiptirHas a block body
  • Basit veya bileşik atama işleçleri içerirContains simple or compound assignment operators
  • Dinamik olarak bağlı bir ifade içerirContains a dynamically bound expression
  • Zaman uyumsuzIs async

Aşağıdaki örneklerde, Func<A,R> türünde bir bağımsız değişken alan A ve türünde bir değer döndüren bir işlevi temsil eden genel bir temsilci türü kullanılır R :The examples that follow use a generic delegate type Func<A,R> which represents a function that takes an argument of type A and returns a value of type R:

delegate R Func<A,R>(A arg);

AtamalarındaIn the assignments

Func<int,int> f1 = x => x + 1;                 // Ok

Func<int,double> f2 = x => x + 1;              // Ok

Func<double,int> f3 = x => x + 1;              // Error

Func<int, Task<int>> f4 = async x => x + 1;    // Ok

Her adsız işlevin parametre ve dönüş türleri, adsız işlevin atandığı değişkenin türünden belirlenir.the parameter and return types of each anonymous function are determined from the type of the variable to which the anonymous function is assigned.

İlk atama, ne zaman tür verildiğinde anonim işlevi temsilci türüne dönüştürür Func<int,int> çünkü bu, türüne x int x+1 örtük olarak dönüştürülebilir geçerli bir ifadedir int .The first assignment successfully converts the anonymous function to the delegate type Func<int,int> because, when x is given type int, x+1 is a valid expression that is implicitly convertible to type int.

Benzer şekilde, Func<int,double> x+1 (türü int ) sonucu türüne örtük olarak dönüştürülebilir olduğundan, ikinci atama anonim işlevi temsilci türüne başarıyla dönüştürür double .Likewise, the second assignment successfully converts the anonymous function to the delegate type Func<int,double> because the result of x+1 (of type int) is implicitly convertible to type double.

Ancak, üçüncü atama bir derleme zamanı hatasıdır çünkü ne zaman, ne zaman, ' x double ın sonucu türüne x+1 double örtülü olarak dönüştürülebilir değildir int .However, the third assignment is a compile-time error because, when x is given type double, the result of x+1 (of type double) is not implicitly convertible to type int.

Dördüncü atama, anonim zaman uyumsuz işlevi temsilci türüne başarıyla dönüştürüyor Func<int, Task<int>> çünkü x+1 (türü) sonucu, int görev türünün sonuç türüne örtük olarak dönüştürülebilir int Task<int> .The fourth assignment successfully converts the anonymous async function to the delegate type Func<int, Task<int>> because the result of x+1 (of type int) is implicitly convertible to the result type int of the task type Task<int>.

Anonim işlevler aşırı yükleme çözünürlüğünü etkileyebilir ve tür çıkarımı içine katılabilir.Anonymous functions may influence overload resolution, and participate in type inference. Daha fazla ayrıntı için bkz. işlev üyeleri .See Function members for further details.

Temsilci türlerine adsız işlev dönüştürmelerini değerlendirmeEvaluation of anonymous function conversions to delegate types

Anonim bir işlevin bir temsilci türüne dönüştürülmesi,, değerlendirme sırasında etkin olan yakalanan dış değişkenlerin adsız işlevine ve (muhtemelen boş) başvuruda bulunduğu bir temsilci örneği oluşturur.Conversion of an anonymous function to a delegate type produces a delegate instance which references the anonymous function and the (possibly empty) set of captured outer variables that are active at the time of the evaluation. Temsilci çağrıldığında, adsız işlevin gövdesi yürütülür.When the delegate is invoked, the body of the anonymous function is executed. Gövdedeki kod, temsilci tarafından başvurulan yakalanan dış değişkenler kümesi kullanılarak yürütülür.The code in the body is executed using the set of captured outer variables referenced by the delegate.

Anonim bir işlevden üretilen temsilcinin çağırma listesi tek bir giriş içerir.The invocation list of a delegate produced from an anonymous function contains a single entry. Temsilcinin tam hedef nesnesi ve Target Yöntemi belirtilmemiş.The exact target object and target method of the delegate are unspecified. Özellikle, temsilcinin hedef nesnesinin, null this kapsayan işlev üyesinin değeri veya başka bir nesne olup olmadığı belirlenmediğini belirtir.In particular, it is unspecified whether the target object of the delegate is null, the this value of the enclosing function member, or some other object.

Aynı temsilci türlerine aynı (muhtemelen boş) yakalanan dış değişken örnekleri kümesine sahip anlamsal özdeş anonim işlevlerin dönüştürülmesine izin verilir (ancak gerekli değildir).Conversions of semantically identical anonymous functions with the same (possibly empty) set of captured outer variable instances to the same delegate types are permitted (but not required) to return the same delegate instance. Aynı bağımsız değişkenlerle aynı etkileri sunan, her durumda, anonim işlevlerin yürütülmesi için, burada anlamsal olarak özdeş terimi kullanılır.The term semantically identical is used here to mean that execution of the anonymous functions will, in all cases, produce the same effects given the same arguments. Bu kural, aşağıdakiler gibi kodun iyileştirilmesine izin verir.This rule permits code such as the following to be optimized.

delegate double Function(double x);

class Test
{
    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void F(double[] a, double[] b) {
        a = Apply(a, (double x) => Math.Sin(x));
        b = Apply(b, (double y) => Math.Sin(y));
        ...
    }
}

İki anonim işlev temsilcisi aynı (boş) yakalanan dış değişken kümesine sahip olduğundan ve anonim işlevler anlam açısından özdeş olduğundan, derleyicinin temsilcilerin aynı hedef yönteme başvurmasına izin verilir.Since the two anonymous function delegates have the same (empty) set of captured outer variables, and since the anonymous functions are semantically identical, the compiler is permitted to have the delegates refer to the same target method. Aslında, derleyicinin hem anonim işlev ifadelerinden çok aynı temsilci örneğini döndürmesine izin verilir.Indeed, the compiler is permitted to return the very same delegate instance from both anonymous function expressions.

İfade ağacı türlerine anonim işlev dönüştürmeleri değerlendirmesiEvaluation of anonymous function conversions to expression tree types

Anonim bir işlevin ifade ağacı türüne dönüştürülmesi bir ifade ağacı (ifade ağacı türleri) oluşturur.Conversion of an anonymous function to an expression tree type produces an expression tree (Expression tree types). Daha kesin olarak, anonim işlev dönüştürmenin değerlendirmesi, anonim işlevin yapısını temsil eden bir nesne yapısının oluşturulmasına yol açar.More precisely, evaluation of the anonymous function conversion leads to the construction of an object structure that represents the structure of the anonymous function itself. İfade ağacının kesin yapısı ve bunu oluşturmak için tam işlem, uygulama tanımlı olur.The precise structure of the expression tree, as well as the exact process for creating it, are implementation defined.

Uygulama örneğiImplementation example

Bu bölümde, diğer C# yapıları açısından anonim işlev dönüştürmelerinden oluşan olası bir uygulama açıklanmaktadır.This section describes a possible implementation of anonymous function conversions in terms of other C# constructs. Burada açıklanan uygulama, Microsoft C# derleyicisi tarafından kullanılan ilkelere dayanır, ancak bu, bir uygulanan uygulamasına ve tek tek mümkün değildir.The implementation described here is based on the same principles used by the Microsoft C# compiler, but it is by no means a mandated implementation, nor is it the only one possible. Bu belirtim, tam semantiği bu şartların kapsamı dışında olduğu için yalnızca Dönüştürmelere ifade ağaçlarına değinmektedir.It only briefly mentions conversions to expression trees, as their exact semantics are outside the scope of this specification.

Bu bölümün geri kalanında, farklı özelliklere sahip anonim işlevler içeren çeşitli kod örnekleri verilmiştir.The remainder of this section gives several examples of code that contains anonymous functions with different characteristics. Her örnek için, yalnızca diğer C# yapılarını kullanan koda karşılık gelen bir çeviri sağlanır.For each example, a corresponding translation to code that uses only other C# constructs is provided. Örneklerde, tanımlayıcı D aşağıdaki temsilci türünü temsil ederek varsayılır:In the examples, the identifier D is assumed by represent the following delegate type:

public delegate void D();

Anonim bir işlevin en basit biçimi, dış değişken içermeyen bir işlevdir:The simplest form of an anonymous function is one that captures no outer variables:

class Test
{
    static void F() {
        D d = () => { Console.WriteLine("test"); };
    }
}

Bu, anonim işlevin kodunun yerleştirildiği bir derleyicinin ürettiği statik metoda başvuran bir temsilci örneklemesine çevrilebilir:This can be translated to a delegate instantiation that references a compiler generated static method in which the code of the anonymous function is placed:

class Test
{
    static void F() {
        D d = new D(__Method1);
    }

    static void __Method1() {
        Console.WriteLine("test");
    }
}

Aşağıdaki örnekte, anonim işlev öğesinin örnek üyelerine başvurur this :In the following example, the anonymous function references instance members of this:

class Test
{
    int x;

    void F() {
        D d = () => { Console.WriteLine(x); };
    }
}

Bu, anonim işlevin kodunu içeren bir derleyici tarafından oluşturulan örnek metoduna çevrilebilir:This can be translated to a compiler generated instance method containing the code of the anonymous function:

class Test
{
    int x;

    void F() {
        D d = new D(__Method1);
    }

    void __Method1() {
        Console.WriteLine(x);
    }
}

Bu örnekte, anonim işlev yerel bir değişken yakalar:In this example, the anonymous function captures a local variable:

class Test
{
    void F() {
        int y = 123;
        D d = () => { Console.WriteLine(y); };
    }
}

Yerel değişkenin kullanım ömrü artık en azından adsız işlev temsilcisinin kullanım ömrüne kadar genişletilmelidir.The lifetime of the local variable must now be extended to at least the lifetime of the anonymous function delegate. Bu, yerel değişken derleyicinin ürettiği bir sınıfın bir alanına "barındırıdırarak" elde edilebilir.This can be achieved by "hoisting" the local variable into a field of a compiler generated class. Yerel değişkenin (yerel değişkenlerin örneklenmesi) örneklenmesi, ardından derleyici tarafından oluşturulan sınıfın bir örneğini oluşturmaya karşılık gelir ve yerel değişkene erişmek, derleyici tarafından oluşturulan sınıfın örneğindeki bir alana erişmeye karşılık gelir.Instantiation of the local variable (Instantiation of local variables) then corresponds to creating an instance of the compiler generated class, and accessing the local variable corresponds to accessing a field in the instance of the compiler generated class. Ayrıca, anonim işlev derleyicinin ürettiği sınıfının örnek yöntemi olur:Furthermore, the anonymous function becomes an instance method of the compiler generated class:

class Test
{
    void F() {
        __Locals1 __locals1 = new __Locals1();
        __locals1.y = 123;
        D d = new D(__locals1.__Method1);
    }

    class __Locals1
    {
        public int y;

        public void __Method1() {
            Console.WriteLine(y);
        }
    }
}

Son olarak, aşağıdaki anonim işlev ve this farklı yaşam sürelerinin bulunduğu iki yerel değişken de yakalar:Finally, the following anonymous function captures this as well as two local variables with different lifetimes:

class Test
{
    int x;

    void F() {
        int y = 123;
        for (int i = 0; i < 10; i++) {
            int z = i * 2;
            D d = () => { Console.WriteLine(x + y + z); };
        }
    }
}

Burada, yerellerin yakalandığı her bir ekstre bloğu için, farklı bloklara ait yerellerin bağımsız yaşam sürelerinin bulunduğu bir derleyici tarafından oluşturulan bir sınıf oluşturulur.Here, a compiler generated class is created for each statement block in which locals are captured such that the locals in the different blocks can have independent lifetimes. Öğesinin bir örneği __Locals2 , iç ifade bloğu için derleyici tarafından oluşturulan sınıf, yerel değişkeni z ve bir örneğine başvuran bir alanı içerir __Locals1 .An instance of __Locals2, the compiler generated class for the inner statement block, contains the local variable z and a field that references an instance of __Locals1. Öğesinin örneği __Locals1 , dış ifade bloğu için derleyici tarafından oluşturulan sınıf, yerel değişkeni y ve kapsayan işlev üyesinin başvurduğu bir alanı içerir this .An instance of __Locals1, the compiler generated class for the outer statement block, contains the local variable y and a field that references this of the enclosing function member. Bu veri yapıları ile, bir örneği aracılığıyla yakalanan tüm dış değişkenlere ulaşmak mümkündür __Local2 ve anonim işlevin kodu bu sınıfın örnek yöntemi olarak uygulanabilir.With these data structures it is possible to reach all captured outer variables through an instance of __Local2, and the code of the anonymous function can thus be implemented as an instance method of that class.

class Test
{
    void F() {
        __Locals1 __locals1 = new __Locals1();
        __locals1.__this = this;
        __locals1.y = 123;
        for (int i = 0; i < 10; i++) {
            __Locals2 __locals2 = new __Locals2();
            __locals2.__locals1 = __locals1;
            __locals2.z = i * 2;
            D d = new D(__locals2.__Method1);
        }
    }

    class __Locals1
    {
        public Test __this;
        public int y;
    }

    class __Locals2
    {
        public __Locals1 __locals1;
        public int z;

        public void __Method1() {
            Console.WriteLine(__locals1.__this.x + __locals1.y + z);
        }
    }
}

Yerel değişkenleri yakalamak için burada uygulanan teknik, anonim işlevler ifade ağaçlarına dönüştürülürken de kullanılabilir: derleyicinin ürettiği nesneler için başvurular ifade ağacında depolanabilir ve yerel değişkenlere erişim bu nesnelerde alan erişimi olarak gösterilebilir.The same technique applied here to capture local variables can also be used when converting anonymous functions to expression trees: References to the compiler generated objects can be stored in the expression tree, and access to the local variables can be represented as field accesses on these objects. Bu yaklaşımın avantajı, "yükseltilmemiş" yerel değişkenlerinin temsilciler ve ifade ağaçları arasında paylaşılmasını olanaklı kılar.The advantage of this approach is that it allows the "lifted" local variables to be shared between delegates and expression trees.

Yöntem grubu dönüştürmeleriMethod group conversions

Bir yöntem grubundan (örtük dönüştürmeler), uyumlu bir temsilci türüne (ifade sınıflandırmaları) sahiptir.An implicit conversion (Implicit conversions) exists from a method group (Expression classifications) to a compatible delegate type. Bir temsilci türü D ve E bir yöntem grubu olarak sınıflandırılan bir ifade verildiğinde, ' den ' a örtük bir dönüştürme, E D E aşağıdaki gibi parametre türleri ve değiştiriciler kullanılarak oluşturulan bir bağımsız değişken listesine, normal biçiminde (uygulanabilir işlev üyesi) geçerli en az bir yöntem içeriyorsa DGiven a delegate type D and an expression E that is classified as a method group, an implicit conversion exists from E to D if E contains at least one method that is applicable in its normal form (Applicable function member) to an argument list constructed by use of the parameter types and modifiers of D, as described in the following.

Bir yöntem grubundan bir temsilci türüne dönüştürmenin derleme zamanı uygulaması, E D aşağıda açıklanmaktadır.The compile-time application of a conversion from a method group E to a delegate type D is described in the following. ' Dan ' a örtük dönüştürmenin mevcut olması, E D dönüştürmenin derleme zamanı uygulamasının hata olmadan başarılı olacağını garanti etmez.Note that the existence of an implicit conversion from E to D does not guarantee that the compile-time application of the conversion will succeed without error.

  • MAşağıdaki değişikliklerle birlikte, formun yöntem çağrısına (Yöntem etkinleştirmeleri) karşılık gelen tek bir yöntem seçilir E(A) :A single method M is selected corresponding to a method invocation (Method invocations) of the form E(A), with the following modifications:
    • Bağımsız değişken listesi A , her biri bir değişken olarak sınıflandırılan ve ref out formal_parameter_list karşılık gelen parametrenin türü ve değiştiricisi (ya da) ile bir ifadeler listesidir D .The argument list A is a list of expressions, each classified as a variable and with the type and modifier (ref or out) of the corresponding parameter in the formal_parameter_list of D.
    • Göz önünde bulundurulması gereken aday yöntemleri yalnızca kendi normal biçimlerinde (uygulanabilir işlev üyesi) uygulanabilen ve yalnızca genişletilmiş biçimlerinde geçerli olan yöntemlerdir.The candidate methods considered are only those methods that are applicable in their normal form (Applicable function member), not those applicable only in their expanded form.
  • Yöntem etkinleştirmeleri algoritması bir hata üretirse, derleme zamanı hatası oluşur.If the algorithm of Method invocations produces an error, then a compile-time error occurs. Aksi takdirde, algoritma aynı sayıda parametreye sahip tek bir en iyi yöntem üretir M D ve dönüştürme var olarak kabul edilir.Otherwise the algorithm produces a single best method M having the same number of parameters as D and the conversion is considered to exist.
  • Seçilen yöntem, M temsilci türüyle uyumlu olmalıdır (temsilci uyumluluğu) D veya aksi halde bir derleme zamanı hatası oluşur.The selected method M must be compatible (Delegate compatibility) with the delegate type D, or otherwise, a compile-time error occurs.
  • Seçilen yöntem M bir örnek yöntemi ise, ile ilişkili örnek ifadesi E temsilcinin hedef nesnesini belirler.If the selected method M is an instance method, the instance expression associated with E determines the target object of the delegate.
  • Seçili Yöntem, bir örnek ifadesinde üye erişimi aracılığıyla belirtilen bir genişletme yöntemi ise, bu örnek ifadesi temsilcinin hedef nesnesini belirler.If the selected method M is an extension method which is denoted by means of a member access on an instance expression, that instance expression determines the target object of the delegate.
  • Dönüştürmenin sonucu  D , bu, seçilen yönteme ve hedef nesneye başvuran yeni oluşturulmuş bir temsilci olan türünde bir değerdir.The result of the conversion is a value of type D, namely a newly created delegate that refers to the selected method and target object.
  • Bu işlemin, bir uzantı yöntemine bir temsilci oluşturulmasına yol açabileceğini unutmayın. Yöntem etkinleştirmeleri algoritması bir örnek Yöntem bulamazsa ancak E(A) bir uzantı yöntemi çağırma (genişletme yöntemi etkinleştirmeleri) olarak çağırma işlemini işlerken başarılı olursa.Note that this process can lead to the creation of a delegate to an extension method, if the algorithm of Method invocations fails to find an instance method but succeeds in processing the invocation of E(A) as an extension method invocation (Extension method invocations). Bu nedenle oluşturulan bir temsilci, Uzantı yönteminin yanı sıra ilk bağımsız değişkenini de yakalar.A delegate thus created captures the extension method as well as its first argument.

Aşağıdaki örnekte, Yöntem grubu dönüştürmeleri gösterilmektedir:The following example demonstrates method group conversions:

delegate string D1(object o);

delegate object D2(string s);

delegate object D3();

delegate string D4(object o, params object[] a);

delegate string D5(int i);

class Test
{
    static string F(object o) {...}

    static void G() {
        D1 d1 = F;            // Ok
        D2 d2 = F;            // Ok
        D3 d3 = F;            // Error -- not applicable
        D4 d4 = F;            // Error -- not applicable in normal form
        D5 d5 = F;            // Error -- applicable but not compatible

    }
}

İçin atama, d1 metot grubunu örtük olarak F bir değere dönüştürür D1 .The assignment to d1 implicitly converts the method group F to a value of type D1.

' A atama, d2 daha az türetilmiş (değişken karşıtı) parametre türleri ve daha türetilmiş (covaryant) dönüş türü olan bir yönteme bir temsilci oluşturmak için nasıl mümkün olduğunu gösterir.The assignment to d2 shows how it is possible to create a delegate to a method that has less derived (contravariant) parameter types and a more derived (covariant) return type.

İçin atama, d3 yöntem geçerli değilse dönüştürmenin nasıl mevcut olmadığını gösterir.The assignment to d3 shows how no conversion exists if the method is not applicable.

İçin atama, d4 yönteminin normal biçiminde nasıl geçerli olması gerektiğini gösterir.The assignment to d4 shows how the method must be applicable in its normal form.

' A atama, d5 temsilcinin ve yöntemin dönüş türlerinin ve yalnızca başvuru türleri için farklı olmasına izin verilip verilmediğini gösterir.The assignment to d5 shows how parameter and return types of the delegate and method are allowed to differ only for reference types.

Diğer tüm örtük ve açık dönüşümlerde olduğu gibi, atama işleci açıkça bir yöntem grubu dönüştürmesi gerçekleştirmek için kullanılabilir.As with all other implicit and explicit conversions, the cast operator can be used to explicitly perform a method group conversion. Bu nedenle örnekThus, the example

object obj = new EventHandler(myDialog.OkClick);

Bunun yerine yazılabilircould instead be written

object obj = (EventHandler)myDialog.OkClick;

Yöntem grupları aşırı yükleme çözümlemesini etkileyebilir ve tür çıkarımı içine katılabilir.Method groups may influence overload resolution, and participate in type inference. Daha fazla ayrıntı için bkz. işlev üyeleri .See Function members for further details.

Bir yöntem grubu dönüşümünün çalışma zamanı değerlendirmesi aşağıdaki gibi devam eder:The run-time evaluation of a method group conversion proceeds as follows:

  • Derleme zamanında seçilen yöntem bir örnek yöntemi ise veya bir örnek yöntemi olarak erişilen bir genişletme yöntemi ise, temsilcinin hedef nesnesi ile ilişkili örnek ifadeden belirlenir E :If the method selected at compile-time is an instance method, or it is an extension method which is accessed as an instance method, the target object of the delegate is determined from the instance expression associated with E:
    • Örnek ifadesi değerlendirilir.The instance expression 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.
    • Örnek ifadesi bir reference_type ise, örnek ifadesi tarafından hesaplanan değer hedef nesne olur.If the instance expression is of a reference_type, the value computed by the instance expression becomes the target object. Seçilen yöntem bir örnek yöntemi ise ve hedef nesne ise null , bir oluşturulur System.NullReferenceException ve başka bir adım yürütülmez.If the selected method is an instance method and the target object is null, a System.NullReferenceException is thrown and no further steps are executed.
    • Örnek ifadesi bir value_type ise, değeri bir nesneye dönüştürmek için bir paketleme Işlemi (kutulama dönüştürmeleri) gerçekleştirilir ve bu nesne hedef nesne haline gelir.If the instance expression is of a value_type, a boxing operation (Boxing conversions) is performed to convert the value to an object, and this object becomes the target object.
  • Aksi takdirde, seçilen yöntem bir statik yöntem çağrısının parçasıdır ve temsilcinin hedef nesnesi olur null .Otherwise the selected method is part of a static method call, and the target object of the delegate is null.
  • 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, derleme zamanında belirlenen yönteme ve yukarıda hesaplanan hedef nesneye bir başvuruya sahip bir başvuru ile başlatılır.The new delegate instance is initialized with a reference to the method that was determined at compile-time and a reference to the target object computed above.