Aracılığıyla paylaş


10 Dönüştürme

10.1 Genel

Dönüştürme, bir ifadenin belirli bir türe dönüştürülmesini veya belirli bir tür olarak kabul edilmesine neden olur; önceki örnekte dönüştürme, gösterimde bir değişiklik içerebilir. Dönüştürmeler örtük veya açık olabilir ve bu, açık bir atama gerekip gerekmediğini belirler.

Örnek: Örneğin, türünden türe intlong dönüştürme örtük olduğundan, türündeki int ifadeler örtük olarak tür longolarak işlenebilir. Türünden türüne longintkarşı dönüştürme açıktır ve bu nedenle açık bir atama gereklidir.

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

son örnek

Bazı dönüştürmeler dile göre tanımlanır. Programlar kendi dönüştürmelerini de tanımlayabilir (§10.5).

Dildeki bazı dönüştürmeler ifadelerden türlere, diğerleri türlerden türlere tanımlanır. Bir türden dönüştürme, bu türe sahip tüm ifadeler için geçerlidir.

Örnek:

enum Color { Red, Blue, Green }

// The expression 0 converts implicitly to enum types
Color c0 = 0;

// Other int expressions need explicit conversion
Color c1 = (Color)1;

// Conversion from null expression (no type) to string
string x = null;

// Conversion from lambda expression to delegate type
Func<int, int> square = x => x * x;

son örnek

10.2 Örtük dönüştürmeler

10.2.1 Genel

Aşağıdaki dönüştürmeler örtük dönüştürmeler olarak sınıflandırılır:

  • Kimlik dönüştürmeleri (§10.2.2)
  • Örtük sayısal dönüştürmeler (§10.2.3)
  • Örtük numaralandırma dönüştürmeleri (§10.2.4)
  • Örtük ilişkilendirilmiş dize dönüştürmeleri (§10.2.5)
  • Örtük başvuru dönüştürmeleri (§10.2.8)
  • Kutulama dönüştürmeleri (§10.2.9)
  • Örtük dinamik dönüştürmeler (§10.2.10)
  • Örtük tür parametre dönüştürmeleri (§10.2.12)
  • Örtük sabit ifade dönüştürmeleri (§10.2.11)
  • Kullanıcı tanımlı (kaldırılmış dahil) örtük dönüştürmeler (§10.2.14)
  • Anonim işlev dönüştürmeleri (§10.2.15)
  • Yöntem grubu dönüştürmeleri (§10.2.15)
  • Null değişmez değer dönüştürmeleri (§10.2.7)
  • Örtük null atanabilir dönüştürmeler (§10.2.6)
  • Örtük tanımlama grubu dönüştürmeleri (§10.2.13)
  • Varsayılan değişmez değer dönüştürmeleri (§10.2.16)
  • Örtük oluşturma dönüştürmeleri (§10.2.17)

Örtük dönüştürmeler, işlev üyesi çağrıları (§12.6.6), atama ifadeleri (§12.9.7) ve atamalar (§12.21) gibi çeşitli durumlarda gerçekleşebilir.

Önceden tanımlanmış örtük dönüştürmeler her zaman başarılı olur ve hiçbir zaman özel durumların oluşturulmasına neden olmaz.

Not: Düzgün tasarlanmış kullanıcı tanımlı örtük dönüştürmeler de bu özellikleri göstermelidir. son not

Dönüştürme amacıyla ve object türleri dynamic kimlik dönüştürülebilir (§10.2.2) şeklindedir.

Ancak dinamik dönüştürmeler (§10.2.10) yalnızca (dynamic) türünde ifadeler için geçerlidir.

10.2.2 Kimlik dönüştürme

Kimlik dönüştürme, herhangi bir türden aynı türe veya çalışma zamanında eşdeğer bir türe dönüştürülür. Bu dönüştürmenin mevcut olmasının bir nedeni, türün T veya tür T ifadesinin kendisine dönüştürülebilir T olarak söylenebilmesidir. Aşağıdaki kimlik dönüştürmeleri vardır:

  • herhangi bir tür Tiçin ve Tarasında T .
  • herhangi bir başvuru türü Tiçin ve T? arasındaT.
  • ile objectarasındadynamic.
  • Her bir öğe türü çifti arasında bir kimlik dönüştürmesi olduğunda, aynı ariteye sahip tüm tanımlama grubu türleri ile buna karşılık gelen yapı ValueTuple<...> türü arasında.
  • Karşılık gelen her tür bağımsız değişkeni arasında bir kimlik dönüştürmesinin bulunduğu aynı genel türden yapılan türler arasında.

Örnek: Aşağıda üçüncü kuralın özyinelemeli yapısı gösterilmektedir:

(int a , string b) t1 = (1, "two");
(int c, string d) t2 = (3, "four");

// Identity conversions exist between
// the types of t1, t2, and t3.
var t3 = (5, "six");
t3 = t2;
t2 = t1;

var t4 = (t1, 7);
var t5 = (t2, 8);

// Identity conversions exist between
// the types of t4, t5, and t6.
var t6 =((8, "eight"), 9);
t6 = t5;
t5 = t4;

demet t1t2 türlerinin ve t3 tümünün iki öğesi vardır: bir int ve ardından bir string. Tanımlama grubu öğesi türleri, , t4ve t5'de t6olduğu gibi tanımlama kümeleri tarafından da olabilir. İç içe tanımlama grupları da dahil olmak üzere ilgili öğe türlerinin her çifti arasında bir kimlik dönüştürmesi vardır; bu nedenle, t4ve t5demet t6türleri arasında bir kimlik dönüştürmesi vardır.

son örnek

Tüm kimlik dönüştürmeleri simetriktir. 'den öğesine T₁T₂bir kimlik dönüştürmesi varsa, 'den T₂T₁öğesine bir kimlik dönüştürmesi vardır. İki tür arasında bir kimlik dönüştürmesi olduğunda iki tür, kimlik dönüştürülebilir .

Çoğu durumda, kimlik dönüştürmenin çalışma zamanında hiçbir etkisi olmaz. Ancak kayan nokta işlemleri türüne göre (§8.3.7) belirtilenden daha yüksek bir hassasiyette gerçekleştirilebileceğinden, sonuçlarının atanması duyarlık kaybına neden olabilir ve açık atamaların, türün (§12.9.7) öngördüğüne duyarlılığı azaltması garanti edilir.

10.2.3 Örtük sayısal dönüştürmeler

Örtük sayısal dönüştürmeler şunlardır:

  • Kaynak: sbyteshort , int, long, float, , doubleveya decimal.
  • Uygulamasından byte , short, ushort, int, , uint, long, ulong, floatveya doubleöğesine.decimal
  • Kaynak: shortint, long, float, doubleveya decimal.
  • Kaynak: ushortint, uint, long, ulong, float, , doubleveya decimal.
  • Kaynaktan intlong , float, doubleveya decimal.
  • Kaynak: uintlong, ulong, float, doubleveya decimal.
  • Kimden long yerine float, doubleveya decimal.
  • Kimden ulong yerine float, doubleveya decimal.
  • Kaynak: charushort, int, uint, long, ulong, , float, doubleveya decimal.
  • float değerinden double değerine.

, , intuintveya longulong ile floatarasında ve oradan veya long oradan ulongdouble dönüştürmeler duyarlık kaybına neden olabilir, ancak hiçbir zaman büyüklük kaybına neden olmaz. Diğer örtük sayısal dönüştürmeler hiçbir zaman bilgi kaybetmez.

Türüne char önceden tanımlanmış örtük dönüştürme yoktur, bu nedenle diğer tam sayı türlerinin değerleri otomatik olarak türüne char dönüştürmez.

10.2.4 Örtük numaralandırma dönüştürmeleri

Örtük numaralandırma dönüştürmesi, herhangi bir tamsayı türüne sahip bir constant_expression (§12.23) ve sıfır değerinin herhangi bir enum_type ve temel türü enum_type olan herhangi bir nullable_value_type dönüştürülmesini sağlar. İkinci durumda dönüştürme, temel alınan enum_type dönüştürülerek ve sonuç kaydırılarak (§8.3.12) değerlendirilir.

10.2.5 Örtük ilişkilendirilmiş dize dönüştürmeleri

Örtük bir ilişkilendirmeli dize dönüştürme, bir interpolated_string_expression (§12.8.3 Bu dönüştürme uygulandığında, ilişkilendirilmiş dizeden bir dize değeri oluşmaz. Bunun yerine , §12.8.3'te System.FormattableStringdaha ayrıntılı olarak açıklandığı gibi bir örneği oluşturulur.

10.2.6 Örtük null atanabilir dönüştürmeler

Örtük null atanabilir dönüştürmeler, örtük önceden tanımlanmış dönüştürmelerden türetilen null atanabilir dönüştürmelerdir (§10.6.1).

10.2.7 Null değişmez değer dönüştürmeleri

Değişmez değerden null herhangi bir başvuru türüne veya null atanabilir değer türüne örtük bir dönüştürme vardır. Hedef türü bir başvuru türü veya verilen null değer türünün null değeri (§8.3.12) ise bu dönüştürme null başvuru oluşturur.

10.2.8 Örtük başvuru dönüştürmeleri

Örtük başvuru dönüştürmeleri şunlardır:

  • ve'e objectherhangi bir dynamic.
  • sağlanan herhangi bir class_type'denS herhangi bir Ttüretilir.S
  • sağlanan herhangi bir herhangi bir SuygularT.S
  • sağlanan herhangi bir interface_type'denS herhangi bir Ttüretilir.S
  • Öğe türüne sahip bir array_typeS öğe türüne Sᵢsahip bir TTᵢ aşağıdakilerin tümü doğruysa:
    • S ve T yalnızca öğe türünde farklılık gösterir. Başka bir deyişle, S aynı T sayıda boyuta sahiptir.
    • 'den öğesine SᵢTᵢörtük bir başvuru dönüştürmesi var.
  • Tek boyutlu bir dizi türünden S[]System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>ve temel arabirimlerine, örtük bir kimlik veya başvuru dönüştürmesi STolması koşuluyla.
  • array_type System.Array ve uyguladığı arabirimlerden.
  • ve uyguladığı arabirimler için herhangi bir System.Delegate.
  • Null değişmez değerden (§6.4.5.7) herhangi bir başvuru türüne.
  • Örtük
  • Örtük bir kimliğe veya bir arabirime veya temsilci türüne başvuru dönüştürmesi varsa ve T varyans-dönüştürülebilir (T₀) ise, herhangiT₀bir reference_type arabirime veya temsilci türüne.T
  • Başvuru türleri olduğu bilinen tür parametrelerini içeren örtük dönüştürmeler. Tür parametreleriyle ilgili örtük dönüştürmeler hakkında daha fazla bilgi için bkz . §10.2.12 .

Örtük başvuru dönüştürmeleri, reference_type'lerarasında yapılan ve her zaman başarılı olduğu kanıtlanabilen ve bu nedenle çalışma zamanında denetim gerektirmeyen dönüştürmelerdir.

Örtük veya açık başvuru dönüştürmeleri, dönüştürülmekte olan nesnenin başvuru kimliğini hiçbir zaman değiştirmez.

Not: Başka bir deyişle, başvuru dönüştürmesi başvurunun türünü değiştirebilir, ancak başvurulmakta olan nesnenin türünü veya değerini hiçbir zaman değiştirmez. son not

10.2.9 Boks dönüştürmeleri

Kutulama dönüştürmesi, bir value_type örtük olarak reference_type dönüştürülmesini sağlar. Aşağıdaki kutulama dönüştürmeleri vardır:

  • Herhangi bir value_type türüne object.
  • Herhangi bir value_type türüne System.ValueType.
  • Herhangi bir enum_type türüne System.Enum.
  • herhangi bir non_nullable_value_type non_nullable_value_type tarafından uygulanan herhangi bir interface_type.
  • Herhangi bir
  • Herhangi bir non_nullable_value_type herhangi bir interface_typeI
  • Herhangi bir nullable_value_type, temel alınan nullable_value_type türünden reference_typebir kutulama dönüştürmesinin olduğu reference_type.
  • Başvuru türü olarak tanınmayan bir tür parametresinden, dönüştürmeye §10.2.12 tarafından izin verilen herhangi bir türe.

Boş değer atanamayan değer türünde bir değerin kutulanması, bir nesne örneğinin atanması ve değerin bu örneğe kopyalanmasından oluşur.

bir nullable_value_type değerinin kutulanması, null değer (HasValueyanlış) veya temel alınan değerin tersini kaldırıp kutulamanın sonucuysa null başvuru oluşturur.

Not: Kutulama işlemi, her değer türü için bir boks sınıfının varlığı açısından hayal edilebilir. Örneğin, adlı struct Sbir I kutulama sınıfı ile arabirimini S_Boxinguygulamayı düşünün.

interface I
{
    void M();
}

struct S : I
{
    public void M() { ... }
}

sealed class S_Boxing : I
{
    S value;

    public S_Boxing(S value)
    {
        this.value = value;
    }

    public void M()
    {
        value.M();
    }
}

Türdeki v bir değeri S kutulama işlemi artık ifadenin new S_Boxing(v) yürütülmesinden ve sonuçta elde edilen örneğin dönüştürmenin hedef türünün değeri olarak döndürülmesinden oluşur. Bu nedenle, deyimleri

S s = new S();
object box = s;

aşağıdakine benzer olarak düşünülebilir:

S s = new S();
object box = new S_Boxing(s);

Yukarıda açıklanan hayal edilen kutulama türü aslında mevcut değildir. Bunun yerine, kutulu değer türü S çalışma zamanı türüne Ssahiptir ve sağ işlenen olarak değer türüne sahip işleci kullanan is bir çalışma zamanı türü denetimi, sol işlenenin sağ işlenenin kutulu bir sürümü olup olmadığını sınar. Örneğin,

int i = 123;
object box = i;
if (box is int)
{
    Console.Write("Box contains an int");
}

aşağıdaki çıkışları oluşturur:

Box contains an int

Kutulama dönüştürmesi, kutulanan değerin bir kopyasının alındığını gösterir. Bu, değerin aynı örneğe başvurmaya devam ettiği ve yalnızca daha az türetilmiş tür olarak kabul edildiği bir reference_type türüne objectobjectdönüştürülmesinden farklıdır. Örneğin, aşağıdakiler

struct Point
{
    public int x, y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

class A
{
    void M() 
    {
        Point p = new Point(10, 10);
        object box = p;
        p.x = 20;
        Console.Write(((Point)box).x);
    }
}

atamasında gerçekleşen örtük kutulama işlemi değerinin kopyalanmasına neden olduğundan konsolunda pbox 10 değerini p verir. Bunun yerine bir Point olarak bildirilmiş olsaydıclass, 20 değeri çıkış olurdu çünkü p ve box aynı örneğe başvuracaktı.

Bir boks sınıfının benzetmesi, kutulamanın kavramsal olarak nasıl çalıştığını resmeden yararlı bir araç olarak kullanılmamalıdır. Bu belirtim tarafından açıklanan davranış ile boks işleminin tam olarak bu şekilde uygulanmasından kaynaklanan davranış arasında çok sayıda ince fark vardır.

son not

10.2.10 Örtük dinamik dönüştürmeler

Dinamik türündeki bir ifadeden herhangi Tbir türe örtük dinamik dönüştürme vardır. Dönüştürme dinamik olarak bağlıdır §12.3.3, yani ifadenin çalışma zamanı türünden Tçalışma zamanında öğesine örtük bir dönüştürme aranır. Dönüştürme bulunmazsa, bir çalışma zamanı özel durumu oluşturulur.

Bu örtük dönüştürme, §10.2'nin başında örtük dönüştürmenin hiçbir zaman özel duruma neden olmamalıdır önerisini ihlal ediyor gibi görünüyor. Ancak, dönüştürmenin kendisi değil, özel duruma neden olan dönüştürmenin bulunmasıdır . Çalışma zamanı özel durumları riski, dinamik bağlamanın kullanımından kaynaklanan bir durumdur. Dönüştürmenin dinamik bağlaması istenmiyorsa, ifade önce öğesine object, sonra da istenen türe dönüştürülebilir.

Örnek: Aşağıda örtük dinamik dönüştürmeler gösterilmektedir:

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

atamaları s2 ve i her ikisi de örtük dinamik dönüştürmeler kullanır ve burada işlemlerin bağlaması çalışma zamanına kadar askıya alınır. Çalışma zamanında, çalışma zamanı türünden (d) hedef türüne stringörtük dönüştürmeler aranır. için bir dönüştürme bulunur, ancak olarak stringbulunmazint.

son örnek

10.2.11 Örtük sabit ifade dönüştürmeleri

Örtük sabit ifade dönüştürmesi aşağıdaki dönüştürmelere izin verir:

  • constant_expression (§12.23
  • constant_expressionlong değeri negatif değilse türündeki bir constant_expression türüne ulongdönüştürülebilir.

10.2.12 Tür parametreleri içeren örtük dönüştürmeler

T için aşağıdaki örtük başvuru dönüştürmeleri (§10.2.8) vardır:

  • 'den T etkin temel sınıfına C, T herhangi bir temel sınıfına Cve T tarafından Cuygulanan herhangi bir arabirime kadar.
  • 'Tnin etkili arabirim kümesindeki bir interface_typeItemel arabirimine Tkadar.
  • From'dan (§15.2.5TU

    Not: Bir başvuru türü olduğu bilindiğinden T , kapsamındaki Tçalışma zamanı türü U , derleme zamanında başvuru türü olarak bilinmese U bile her zaman bir başvuru türü olacaktır. son not

  • Null değişmez değerden (§6.4.5.7) T'ye.

Başvuru türü olarak bilinen bir type_parameterT için §15.2.5, aşağıdaki dönüştürmeler derleme zamanında kutulama dönüştürmeleri (T) olarak kabul edilir. Çalışma zamanında, bir değer türüyse T , dönüştürme bir kutulama dönüştürmesi olarak yürütülür. Çalışma zamanında, bir başvuru türüyse T , 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.

  • 'den T etkin temel sınıfına C, T herhangi bir temel sınıfına Cve T tarafından Cuygulanan herhangi bir arabirime kadar.

    Not: C , System.Objectveya System.ValueType türlerinden System.Enumbiri olacaktır (aksi takdirde T başvuru türü olarak bilinir). son not

  • 'Tnin etkili arabirim kümesindeki bir interface_typeItemel arabirimine Tkadar.

Başvuru türü olmadığı bilinmeyen bir type_parameterT için, türü parametresine T bağımlı Uolan T örtük bir dönüştürme U vardır. Çalışma zamanında, bir değer türü ve T başvuru türüyseU, dönüştürme bir kutulama dönüştürmesi olarak yürütülür. Çalışma zamanında, hem hem T de U değer türleriyse T ve U mutlaka aynı türdeyse ve dönüştürme gerçekleştirilmediyse. Çalışma zamanında, bir başvuru türüyse T , U mutlaka bir başvuru türüdür ve dönüştürme örtük başvuru dönüştürme veya kimlik dönüştürme (§15.2.5) olarak yürütülür.

Belirli bir tür parametresi Tiçin aşağıdaki daha örtük dönüştürmeler vardır:

  • Bir başvuru türüne örtük bir dönüştürmesi varsa ve T kimlik dönüştürmesi varsa, kimden'den S başvuru türüne.S₀S₀S Çalışma zamanında dönüştürme, dönüştürme ile aynı şekilde S₀yürütülür.
  • Bir arabirim türüne örtük dönüştürmesi varsa ve (§18.2.3.3) için varyans-dönüştürülebilirse, Kimden'den T arabirim türüne II₀I₀ Çalışma zamanında, bir değer türüyse T , dönüştürme bir kutulama dönüştürmesi olarak yürütülür. 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.

Her durumda kurallar, yalnızca çalışma zamanında dönüştürme bir değer türünden başvuru türüne ise bir dönüştürmenin kutulama dönüştürmesi olarak yürütülmesini sağlar.

10.2.13 Örtük tanımlama grubu dönüştürmeleri

bir tanımlama grubu ifadesinden E tanımlama grubu türüne T örtük dönüştürme, ile aynı arity'ye E sahipse T ve içindeki her öğeden içindeki E ilgili öğe türüne Törtük dönüştürme varsa. Dönüştürme işlemi, 'nin karşılık gelen T türünün bir örneği System.ValueTuple<...>oluşturularak ve alanlarının her birini soldan sağa doğru sırasıyla başlatarak, bulunan örtük dönüştürmeyi kullanarak ilgili tanımlama grubu öğe ifadesini Edeğerlendirerek T ve alanı sonuçla başlatarak gerçekleştirilir.

Tanımlama grubu ifadesindeki bir öğe adı tanımlama grubu türündeki karşılık gelen öğe adıyla eşleşmiyorsa, bir uyarı verilir.

Örnek:

(int, string) t1 = (1, "One");
(byte, string) t2 = (2, null);
(int, string) t3 = (null, null);        // Error: No conversion
(int i, string s) t4 = (i: 4, "Four");
(int i, string) t5 = (x: 5, s: "Five"); // Warning: Names are ignored

Öğe ifadelerinden ilgili öğe türlerine t1örtük dönüştürmeler mevcut olduğundan, , t2ve t4t5 bildirimlerinin tümü geçerlidir. 'den t3 'a nulldönüştürme olmadığından bildirimi int geçersiz. tanımlama grubu t5 ifadesindeki öğe adları tanımlama grubu türündekilerden farklı olduğundan bildirimi bir uyarıya neden olur.

son örnek

10.2.14 Kullanıcı tanımlı örtük dönüştürmeler

Kullanıcı tanımlı örtük dönüştürme, isteğe bağlı bir standart örtük dönüştürmeden, ardından kullanıcı tanımlı örtük dönüştürme işlecinin yürütülmesinden ve ardından başka bir isteğe bağlı standart örtük dönüştürmeden oluşur. Kullanıcı tanımlı örtük dönüştürmeleri değerlendirmek için tam kurallar §10.5.4'te açıklanmıştır.

10.2.15 Anonim işlev dönüştürmeleri ve yöntem grubu dönüştürmeleri

Anonim işlevlerin ve yöntem gruplarının kendi içinde türleri yoktur, ancak örtük olarak temsilci türlerine dönüştürülebilirler. Ayrıca, bazı lambda ifadeleri örtük olarak ifade ağacı türlerine dönüştürülebilir. Anonim işlev dönüştürmeleri §10.7 ve yöntem grubu dönüştürmeleri §10.8'de daha ayrıntılı olarak açıklanmıştır.

10.2.16 Varsayılan değişmez değer dönüştürmeleri

Bir default_literal (§12.8.21) herhangi bir türe örtük dönüştürme vardır. Bu dönüştürme, çıkarsanan türün varsayılan değerini (§9,3) oluşturur.

10.2.17 Örtük oluşturma dönüştürmeleri

Throw ifadeleri bir türe sahip olmasa da, örtük olarak herhangi bir türe dönüştürülebilir.

10.3 Açık dönüştürmeler

10.3.1 Genel

Aşağıdaki dönüştürmeler açık dönüştürmeler olarak sınıflandırılır:

  • Tüm örtük dönüştürmeler (§10.2)
  • Açık sayısal dönüştürmeler (§10.3.2)
  • Açık numaralandırma dönüştürmeleri (§10.3.3)
  • Açık null atanabilir dönüştürmeler (§10.3.4)
  • Açık tanımlama grubu dönüştürmeleri (§10.3.6)
  • Açık başvuru dönüştürmeleri (§10.3.5)
  • Açık arabirim dönüştürmeleri
  • Kutulama dönüştürmeleri (§10.3.7)
  • Açık tür parametre dönüştürmeleri (§10.3.8)
  • Kullanıcı tanımlı açık dönüştürmeler (§10.3.9)

Açık dönüştürmeler, atama ifadelerinde (§12.9.7) oluşabilir.

Açık dönüştürme kümesi tüm örtük dönüştürmeleri içerir.

Not: Bu, örneğin, belirli bir yöntem aşırı yüklemesinin seçilmesini zorlamak için örtük bir kimlik dönüştürmesi mevcut olduğunda açık bir atamanın kullanılmasına izin verir. son not

Örtük dönüştürmeler olmayan açık dönüştürmeler, her zaman başarılı olduğu kanıtlanamayan dönüştürmeler, bilgileri kaybetme olasılığı bilinen dönüştürmeler ve açık gösterimin yerine getirilmesinden yeterince farklı türlerin etki alanları arasında yapılan dönüştürmelerdir.

10.3.2 Açık sayısal dönüştürmeler

Açık sayısal dönüştürmeler, örtük sayısal dönüştürmenin (§10.2.3) henüz mevcut olmadığı bir numeric_type başka bir numeric_type dönüştürmeleridir:

  • Kaynak: sbytebyte, ushort, uint, ulongveya char.
  • Kimden byte veya öğesine.sbytechar
  • Kaynak: shortsbyte , byte, ushort, uint, , ulongveya char.
  • Kaynaktan ushortsbyte , byte, shortveya char.
  • Kaynak: intsbyte, byte, short, ushort, uint, , ulongveya char.
  • Kaynak: uintsbyte , byte, short, ushort, , intveya char.
  • Kaynak: longsbyte, byte, short, ushort, int, , uint, ulongveya char.
  • Kaynak: ulongsbyte, byte, short, ushort, int, , uint, longveya char.
  • Kimden char yerine sbyte, byteveya short.
  • Kaynak: floatsbyte, byte, short, ushort, int, uint, , long, ulong, charveya decimal.
  • Kaynak: doublesbyte , byte, short, ushort, int, uint, , long, ulong, char, floatveya decimal.
  • Kaynak: decimalsbyte , byte, short, ushort, int, uint, , long, ulong, char, floatveya double.

Açık dönüştürmeler tüm örtük ve açık sayısal dönüştürmeleri içerdiğinden, bir atama ifadesi (§12.9.7) kullanarak herhangi bir numeric_type başka bir numeric_type dönüştürmek her zaman mümkündür.

Açık sayısal dönüştürmeler büyük olasılıkla bilgileri kaybeder veya büyük olasılıkla özel durumların oluşturulmasına neden olur. Açık bir sayısal dönüştürme aşağıdaki gibi işlenir:

  • Bir integral türünden başka bir integral türüne dönüştürme için işleme, dönüştürmenin gerçekleştiği taşma denetimi bağlamı (§12.8.20) bağlıdır:
    • Bir checked bağlamda, kaynak işlenenin değeri hedef türün aralığı içindeyse dönüştürme başarılı olur, ancak kaynak işlenenin değeri hedef türün aralığının dışındaysa bir System.OverflowException oluşturur.
    • Bir unchecked bağlamda dönüştürme her zaman başarılı olur ve aşağıdaki gibi devam eder.
      • Kaynak türü hedef türden büyükse, kaynak değeri "ek" en önemli bitleri atılarak kesilir. Sonuç daha sonra hedef türün değeri olarak değerlendirilir.
      • Kaynak türü hedef türle aynı boyuttaysa, kaynak değer hedef türün değeri olarak değerlendirilir
  • bir decimal tam sayı türüne dönüştürme için, kaynak değer sıfıra doğru en yakın tam sayı değerine yuvarlanir ve bu tam sayı değeri dönüştürmenin sonucu olur. Sonuçta elde edilen tam sayı değeri hedef türün aralığının dışındaysa, bir System.OverflowException oluşturulur.
  • bir tamser türünden float veya double tam sayı türüne dönüştürme için işleme, dönüştürmenin gerçekleştiği taşma denetimi bağlamı (§12.8.20) bağlıdır:
    • denetlenen bir bağlamda dönüştürme aşağıdaki gibi devam eder:
      • İşlenenin değeri NaN veya sonsuzsa, bir System.OverflowException oluşturulur.
      • Aksi takdirde, kaynak işlenen sıfıra doğru en yakın tam sayı değerine yuvarlanir. Bu tam sayı değeri hedef türün aralığı içindeyse, bu değer dönüştürmenin sonucudur.
      • Aksi takdirde, bir System.OverflowException oluşturulur.
    • İşaretlenmemiş bir bağlamda dönüştürme her zaman başarılı olur ve aşağıdaki gibi devam eder.
      • İşlenenin değeri NaN veya sonsuz ise, dönüştürmenin sonucu hedef türün belirtilmemiş bir değeridir.
      • Aksi takdirde, kaynak işlenen sıfıra doğru en yakın tam sayı değerine yuvarlanir. Bu tam sayı değeri hedef türün aralığı içindeyse, bu değer dönüştürmenin sonucudur.
      • Aksi takdirde, dönüştürmenin sonucu hedef türün belirtilmemiş bir değeridir.
  • 'den değerine doublefloatdouble dönüştürme için, değer en float yakın değere yuvarlanir. double Değer olarak floattemsil etmek için çok küçükse, sonuç değerle aynı işaretle sıfır olur. Değerin double büyüklüğü bir olarak floattemsil edilemeyecek kadar büyükse, sonuç değerle aynı işaretle sonsuz olur. double Değer NaN ise, sonuç da NaN olur.
  • veya 'den float dönüştürme içindouble, kaynak değer gösterime decimal dönüştürülür ve gerekirse en yakın sayıya yuvarlanir (decimal).
    • Kaynak değer olarak temsil decimaletmek için çok küçükse, sonuç sıfır olur ve imzalı sıfır değerlerini destekliyorsa decimal özgün değerin işaretini korur.
    • Kaynak değerin büyüklüğü , olarak decimaltemsil edilemeyecek kadar büyükse veya bu değer sonsuz ise, ondalık gösterimi sonsuzları destekliyorsa, sonuç özgün değerin işaretini sonsuza kadar korur; aksi takdirde System.OverflowException oluşturulur.
    • Kaynak değer NaN ise, ondalık gösterimi NaN'leri destekliyorsa sonuç NaN olur; aksi takdirde bir System.OverflowException oluşturulur.
  • veya decimalfloat olan doubledecimal bir dönüştürme için, değer en double yakın veya float değere yuvarlanmış. Kaynak değerin büyüklüğü hedef türde temsil edilemeyecek kadar büyükse veya bu değer sonsuzsa, sonuç sonsuzdur ve özgün değerin işaretini korur. Kaynak değer NaN ise, sonuç NaN olur. Bu dönüştürme duyarlığı kaybedebilir, ancak hiçbir zaman bir özel durumun atılması neden olmaz.

Not: Türdecimal, sonsuzluk veya NaN değerlerini desteklemek için gerekli değildir, ancak bunu yapabilir; aralığı ve floataralığından double küçük olabilir, ancak olması garanti edilmemektedir. Sonsuz veya NaN değeri olmayan ve değerinden küçük decimalbir aralığa sahip gösterimler içinfloat, ya da hiçbir zaman sonsuz ya da decimalfloat NaN olmayacak şekilde dönüştürmenin double sonucu. son not

10.3.3 Açık numaralandırma dönüştürmeleri

Açık numaralandırma dönüştürmeleri şunlardır:

  • sbyte, , byte, short, ushort, , int, , uint, long, ulong, char, float, doubleveya decimal herhangi bir enum_type.
  • herhangi bir enum_type , sbytebyte, short, , ushort, int, uint, , long, ulongcharfloatdoubleveya .decimal
  • Herhangi bir enum_type diğer enum_type.

İki tür arasındaki açık bir numaralandırma dönüştürmesi, katılan enum_type bu enum_type temel türü olarak kabul edilmesi ve ardından sonuçta elde edilen türler arasında örtük veya açık bir sayısal dönüştürme gerçekleştirilmesiyle işlenir.

Örnek: Altında yatan türüne sahip bir Eint verildiğinde, E'dan byte'ye dönüştürme, 'dan int'e açık bir sayısal dönüştürme (byte) olarak işlenir ve byte'den E'e dönüştürme, 'dan byte'ye örtük bir sayısal dönüştürme (int) olarak işlenir. son örnek

10.3.4 Açık null atanabilir dönüştürmeler

Açık null atanabilir dönüştürmeler, açık ve örtük önceden tanımlanmış dönüştürmelerden türetilen null atanabilir dönüştürmelerdir (§10.6.1).

10.3.5 Açık başvuru dönüştürmeleri

Açık başvuru dönüştürmeleri şunlardır:

  • Nesneden diğer reference_type.
  • Herhangi bir class_typeS herhangi bir class_typeTiçin temel sınıfı SsağlanırT.
  • Herhangi bir class_typeS herhangi bir interface_typeTSsağlanan korumalı değildir ve sağlandığında S uygulanmaz.T
  • Herhangi bir interface_typeS herhangi bir , sağlanan T korumalı değildir veya sağlanan T uygularT.
  • Sağlanan herhangi bir interface_typeS interface_type T' den Stüretilmemiştir.
  • Öğe türüne sahip bir array_typeS öğe türüne Sᵢsahip bir TTᵢ aşağıdakilerin tümü doğruysa:
    • S ve T yalnızca öğe türünde farklılık gösterir. Başka bir deyişle, S aynı T sayıda boyuta sahiptir.
    • 'den öğesine SᵢTᵢaçık bir başvuru dönüştürmesi var.
  • ve System.Array uyguladığı arabirimlerden herhangi bir array_type.
  • tek boyutlu , S[]ve temel arabirimlerine, kimlik dönüştürmesi veya açık başvuru dönüştürmesi System.Collections.Generic.IList<T>System.Collections.Generic.IReadOnlyList<T>olması koşuluyla.
  • System.Collections.Generic.IList<S>kimlik dönüştürmesi veya T'den açık başvuru dönüştürmesi olması koşuluyla , System.Collections.Generic.IReadOnlyList<S>ve temel arabirimlerinden T[] tek boyutlu bir dizi türüneS.
  • ve System.Delegate uyguladığı arabirimlerden herhangi bir delegate_type.
  • Bir başvuru türünden S başvuru türüne T açık başvuru dönüştürmesi varsa ve S 'den T₀ öğesine bir kimlik dönüştürmesi varsa, başvuru türünden T₀ başvuru türüneT₀.T
  • Bir başvuru türünden bir arabirime veya temsilci türüne açık bir başvuru dönüştürmesi S varsa ve T varyans-dönüştürülebilir S veya varyans-convertible - §18.2.3.3T₀.T₀
  • Kimden'e, genel bir temsilci türü olan, D<S₁...Sᵥ> ile uyumlu veya ile aynı D<T₁...Tᵥ>olmayan ve aşağıdakilerin her tür parametresi D<X₁...Xᵥ>D<S₁...Sᵥ> için:D<T₁...Tᵥ>XᵢD
    • Sabitse Xᵢ , Sᵢ ile Tᵢaynıdır.
    • Birlikte değişkense Xᵢ bir kimlik dönüştürmesi, örtük başvuru dönüştürmesi veya açık başvuru dönüştürmesi vardır SᵢTᵢ.
    • Değişken karşıtıysa Xᵢ , SᵢTᵢ aynı veya her iki başvuru türü de aynı olur.
  • Başvuru türleri olduğu bilinen tür parametreleri içeren açık dönüştürmeler. Tür parametreleriyle ilgili açık dönüştürmeler hakkında daha fazla bilgi için bkz . §10.3.8.

Açık başvuru dönüştürmeleri, reference_typearasında yapılan ve doğru olduklarından emin olmak için çalışma zamanı denetimleri gerektiren dönüştürmelerdir.

Açık başvuru dönüştürmesinin çalışma zamanında başarılı olması için, kaynak işlenenin değeri olacaktır nullveya kaynak işlenen tarafından başvurulan nesnenin türü örtük başvuru dönüştürmesi (§10.2.8) ile hedef türe dönüştürülebilecek bir tür olmalıdır. Açık başvuru dönüştürmesi başarısız olursa, bir System.InvalidCastException oluşturulur.

Not: Örtük veya açık başvuru dönüştürmeleri, hiçbir zaman başvurunun değerini (§8.2.1), yalnızca türünü değiştirmez; başvurulan nesnenin türünü veya değerini de değiştirmez. son not

10.3.6 Açık tanımlama grubu dönüştürmeleri

ile aynı arity'ye E sahipse T ve içindeki her öğeden E içindeki ilgili öğe türüne T örtük veya açık bir dönüştürme varsa, bir tanımlama grubu ifadesinden E bir tanımlama grubu türüne Taçık dönüştürme vardır. Dönüştürme, karşılık gelen T türünün bir örneği System.ValueTuple<...>oluşturularak ve alanlarının her biri soldan sağa doğru başlatılarak, öğesinin karşılık gelen tanımlama grubu öğesi ifadesi Edeğerlendirilerek, bulunan açık dönüştürmeyi kullanarak ilgili öğe türüne T dönüştürülerek ve alanı sonuçla başlatarak gerçekleştirilir.

10.3.7 Kutulama dönüştürmelerini kaldırma

Kutulama dönüştürmesi, bir reference_type açıkça bir value_type dönüştürülmesini sağlar. Aşağıdaki kutulama dönüştürmeleri vardır:

  • Türünden object herhangi bir value_type.
  • Türünden System.ValueType herhangi bir value_type.
  • Türünden System.Enum herhangi bir enum_type.
  • Herhangi bir interface_type interface_type uygulayan herhangi bir non_nullable_value_type.
  • bir interface_type'den non_nullable_valueInon_nullable_value_type.
  • bir interface_typeInon_nullable_value_type gelen ve variance_convertible I₀ veya I₀'a dönüştürülebilir (I) olduğu herhangi bir II₀non_nullable_value_type.
  • Herhangi bir reference_type, reference_type nullable_value_type temelnon_nullable_value_type bir kutulama dönüştürmesinin olduğu herhangi bir nullable_value_type.
  • Değer türü olarak tanınmayan bir tür parametresinden, dönüştürmeye §10.3.8 tarafından izin verilen herhangi bir türe.

bir non_nullable_value_type kutulama işlemi, önce nesne örneğinin verilen non_nullable_value_type kutulanmış değeri olup olmadığını denetlemeyi ve ardından değeri örneğin dışına kopyalamayı içerir.

Bir nullable_value_type gelen kutulama, kaynak işlenen ise nullable_value_typenullveya nesne örneğini nullable_value_type temel alınan türüne geri alma işleminin sarmalanmış sonucunu oluşturur.

Not: §10.2.9'da açıklanan sanal kutulama sınıfına başvuruda bulunarak, nesne kutusunun value_typeifadesinin Syürütülmesinden oluşur. Bu nedenle, deyimleri

object box = new S();
S s = (S)box;

kavramsal olarak

object box = new S_Boxing(new S());
S s = ((S_Boxing)box).value;

son not

Belirli bir non_nullable_value_type gelen kutu açma işleminin çalışma zamanında başarılı olması için, kaynak işlenenin değeri bu non_nullable_value_type kutulanmış değerine başvuru olmalıdır. Kaynak işlenen null bir System.NullReferenceException ise oluşturulur. Kaynak işlenen uyumsuz bir nesneye başvuruysa, bir System.InvalidCastException oluşturulur.

Belirli bir nullable_value_type gelen kutu açma işleminin çalışma zamanında başarılı olması için, kaynak işlenenin değeri null veya nullable_value_type temel non_nullable_value_typekutulanmış değerine başvuru olmalıdır. Kaynak işlenen uyumsuz bir nesneye başvuruysa, bir System.InvalidCastException oluşturulur.

10.3.8 Tür parametreleri içeren açık dönüştürmeler

Başvuru türü (§15.2.5) olarak bilinen bir type_parameter T için aşağıdaki açık başvuru dönüştürmeleri (§10.3.5) vardır:

  • öğesinin etkin temel sınıfından herhangi C bir temel sınıfına TT ve öğesine kadarC.T
  • herhangi bir interface_type'den öğesine.T
  • 'den T öğesine örtük bir başvuru dönüştürmesi olmaması koşuluyla herhangi bir interface_type.IT
  • (§15.2.5olan U bir TT sağlanana kadar.

    Not: Bir başvuru türü olduğu bilindiğinden T , kapsamında T, derleme zamanında başvuru türü olarak bilinmese U bile, çalışma zamanı türünüz her zaman bir başvuru türü olacaktır. son not

Başvuru türü (§15.2.5) olarak bilinmeyen bir T için, aşağıdaki dönüştürmeler derleme zamanında gelen dönüştürmeleri () kaldırma olarak kabul edilir.T Çalışma zamanında, bir değer türüyse T dönüştürme, kutu açma dönüştürmesi olarak yürütülür. Çalışma zamanında, bir başvuru türüyse T , 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.

  • öğesinin etkin temel sınıfından herhangi C bir temel sınıfına TT ve öğesine kadarC.T

    Not: C, , System.Objectveya System.ValueType türlerinden System.Enumbiri olacaktır (aksi takdirde T başvuru türü olarak bilinir). son not

  • herhangi bir interface_type'den öğesine.T

Başvuru türü (§15.2.5) olarak bilinmeyen bir type_parameter T için aşağıdaki açık dönüştürmeler vardır:

  • 'den T herhangi bir için zaten örtük bir dönüştürme ITyoktur. Bu dönüştürme, örtük bir kutulama dönüştürmesinden (§10.2.9) Tobject ve ardından açık bir başvuru dönüştürmesinden objectIoluşur. Çalışma zamanında, bir değer türüyse T dönüştürme, bir kutulama dönüştürmesi ve ardından açık başvuru dönüştürmesi olarak yürütülür. Çalışma zamanında, bir başvuru türüyse T , dönüştürme açık bir başvuru dönüştürmesi olarak yürütülür.
  • (U) öğesine bağlı T olan T bir tür parametresinden U sağlanana kadar. Çalışma zamanında, bir değer türü ve T başvuru türüyse U dönüştürme, kutu açma dönüştürmesi olarak yürütülür. Çalışma zamanında, hem hem T de U değer türleriyse T ve U mutlaka aynı türdeyse ve dönüştürme gerçekleştirilmediyse. Çalışma zamanında, bir başvuru türüyse T , U mutlaka bir başvuru türüdür ve dönüştürme açık başvuru dönüştürmesi veya kimlik dönüştürmesi olarak yürütülür.

Her durumda kurallar, dönüştürmenin yalnızca çalışma zamanında bir başvuru türünden bir değer türüne olması durumunda bir dönüştürmenin kutu açma dönüştürmesi olarak yürütülmesini sağlar.

Yukarıdaki kurallar, kısıtlanmamış bir tür parametresinden arabirim olmayan bir türe doğrudan açık dönüştürmeye izin vermez ve bu şaşırtıcı olabilir. Bu kuralın nedeni karışıklığı önlemek ve bu tür dönüştürmelerin semantiğini net hale getirmektir.

Örnek: Aşağıdaki bildirimi göz önünde bulundurun:

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

öğesinin doğrudan açık dönüştürmesine tlong izin verilseydi, bunun döndüreceği X<int>.F(7)7Lkolayca beklenebilirdi. Ancak, standart sayısal dönüştürmeler yalnızca türlerin bağlama zamanında sayısal olduğu bilindiğinde dikkate alındığından, bu kabul edilmez. Semantiği net hale getirmek için yukarıdaki örneğin yazılması gerekir:

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 derlenecek ancak çalıştırıldığında X<int>.F(7) bir kutulu int doğrudan 'a dönüştürülemeyeceğinden longçalışma zamanında bir özel durum oluşturacaktır.

son örnek

10.3.9 Kullanıcı tanımlı açık dönüştürmeler

Kullanıcı tanımlı açık dönüştürme, isteğe bağlı standart açık dönüştürmeden, ardından kullanıcı tanımlı örtük veya açık dönüştürme işlecinin yürütülmesinden ve ardından başka bir isteğe bağlı standart açık dönüştürmeden oluşur. Kullanıcı tanımlı açık dönüştürmeleri değerlendirmek için kesin kurallar §10.5.5'te açıklanmıştır.

10.4 Standart dönüştürmeler

10.4.1 Genel

Standart dönüştürmeler, kullanıcı tanımlı bir dönüştürmenin parçası olarak gerçekleşebilecek önceden tanımlanmış dönüştürmelerdir.

10.4.2 Standart örtük dönüştürmeler

Aşağıdaki örtük dönüştürmeler standart örtük dönüştürmeler olarak sınıflandırılır:

  • Kimlik dönüştürmeleri (§10.2.2)
  • Örtük sayısal dönüştürmeler (§10.2.3)
  • Örtük null atanabilir dönüştürmeler (§10.2.6)
  • Null değişmez değer dönüştürmeleri (§10.2.7)
  • Örtük başvuru dönüştürmeleri (§10.2.8)
  • Kutulama dönüştürmeleri (§10.2.9)
  • Örtük sabit ifade dönüştürmeleri (§10.2.11)
  • Tür parametrelerini içeren örtük dönüştürmeler (§10.2.12)

Standart örtük dönüştürmeler özellikle kullanıcı tanımlı örtük dönüştürmeleri dışlar.

10.4.3 Standart açık dönüştürmeler

Standart açık dönüştürmelerin tümü standart örtük dönüştürmelerin yanı sıra karşı standart örtük dönüştürmenin bulunduğu açık dönüştürmelerin alt kümesidir.

Not: Başka bir deyişle, bir türünden türüne A standart örtük dönüştürme varsa, türünden türüne BA ve türünden BB türüne Astandart bir açık dönüştürme vardır. son not

10.5 Kullanıcı tanımlı dönüştürmeler

10.5.1 Genel

C# önceden tanımlanmış örtük ve açık dönüştürmelerin kullanıcı tanımlı dönüştürmelerle genişletilmesine olanak tanır. Kullanıcı tanımlı dönüştürmeler, sınıf ve yapı türlerinde dönüştürme işleçleri (§15.10.4) bildirilerek sunulur.

10.5.2 İzin verilen kullanıcı tanımlı dönüştürmeler

C# yalnızca belirli kullanıcı tanımlı dönüştürmelerin bildirilmesine izin verir. Özellikle, zaten var olan örtük veya açık dönüştürmeyi yeniden tanımlamak mümkün değildir.

Belirli bir kaynak türü S ve hedef türü Tiçin, null atanabilir değer türleriyse S veya T varsa, temel türlerine izin verin S₀ ve T₀ başvuruda bulunalım; aksi halde S₀ ve T₀ sırasıyla eşit S olur T . Bir sınıfın veya yapının, yalnızca aşağıdakilerin tümü doğru olduğunda kaynak türden S hedef türe T dönüştürme bildirmesine izin verilir:

  • S₀ ve T₀ farklı türlerdir.
  • veya S₀T₀ işleç bildiriminin gerçekleştiği sınıf veya yapı türüdür.
  • Ne S₀ de T₀ interface_type.
  • Kullanıcı tanımlı dönüştürmeler hariç, 'den veya öğesine STTSdönüştürme yoktur.

Kullanıcı tanımlı dönüştürmeler için geçerli olan kısıtlamalar §15.10.4'te belirtilir.

10.5.3 Kullanıcı tanımlı dönüştürmelerin değerlendirilmesi

Kullanıcı tanımlı dönüştürme, kaynak türü olabilecek bir kaynak ifadeyi hedef tür olarak adlandırılan başka bir türe dönüştürür. Kaynak ifade ve hedef türü için en özel kullanıcı tanımlı dönüştürme işlecini bulmaya yönelik kullanıcı tanımlı dönüştürme merkezlerinin değerlendirilmesi. Bu belirleme birkaç adıma ayrılır:

  • Kullanıcı tanımlı dönüştürme işleçlerinin dikkate alınacağı sınıf ve yapı kümesini bulma. Bu küme, kaynak türü ve kaynak türü varsa temel sınıflarının yanı sıra hedef türü ve temel sınıflarından oluşur. Bu amaçla, yalnızca sınıfların ve yapıların kullanıcı tanımlı işleçler bildirebileceği ve sınıf dışı türlerin temel sınıfları olmadığı varsayılır. Ayrıca, kaynak veya hedef türü null atanabilir-değer türündeyse, bunun yerine temel türü kullanılır.
  • Bu tür kümesinden, hangi kullanıcı tanımlı ve kaldırılmış dönüştürme işleçlerinin geçerli olduğunu belirleme. Bir dönüştürme işlecinin uygulanabilir olması için, kaynak ifadeden işlecin işlenen türüne standart bir dönüştürme (§10.4) gerçekleştirilebilir ve işlecin sonuç türünden hedef türüne standart dönüştürme gerçekleştirilebilir.
  • Geçerli kullanıcı tanımlı işleç kümesinden, hangi işlecin kesin olarak en özel olduğunu belirleyin. Genel olarak, en özel işleç, işlenen türü kaynak ifadeye "en yakın" olan ve sonuç türü hedef türe "en yakın" olan işleçtir. Kullanıcı tanımlı dönüştürme işleçleri, kaldırılan dönüştürme işleçlerine göre tercih edilir. En özel kullanıcı tanımlı dönüştürme işlecini oluşturmaya yönelik tam kurallar aşağıdaki alt kodlarda tanımlanır.

En özel kullanıcı tanımlı dönüştürme işleci belirlendikten sonra, kullanıcı tanımlı dönüştürmenin gerçek yürütülmesi en fazla üç adımdan oluşur:

  • İlk olarak, gerekirse kaynak ifadeden kullanıcı tanımlı veya kaldırılmış dönüştürme işlecinin işlenen türüne standart bir dönüştürme gerçekleştirin.
  • Ardından, dönüştürmeyi gerçekleştirmek için kullanıcı tanımlı veya kaldırılan dönüştürme işlecini çağırın.
  • Son olarak gerekirse, kullanıcı tanımlı dönüştürme işlecinin sonuç türünden hedef türüne standart bir dönüştürme gerçekleştirin.

Kullanıcı tanımlı dönüştürmenin değerlendirilmesi hiçbir zaman birden fazla kullanıcı tanımlı veya kaldırılmış dönüştürme işlecini içermez. Başka bir deyişle, türünden türe ST dönüştürme, önce 'den SX kullanıcı tanımlı bir dönüştürmeyi yürütmez ve sonra kullanıcı tanımlı bir dönüştürmeyi 'den X 'a yürütmez T.

  • Kullanıcı tanımlı örtük veya açık dönüştürmelerin tam değerlendirme tanımları aşağıdaki alt öğelerde verilmiştir. Tanımlar aşağıdaki terimleri kullanır:
  • Eğer bir tür 'den türüne standart bir örtük dönüştürme (§10.4.2) varsa ve ne ne de interface_typeise, 'intarafından olduğu söylenir ve 'ünkapsadığı söylenir.
  • bir ifadeden türüne standart örtük dönüştürme (§10.4.2) varsa ve veya türü (varsa) interface_typeise, tarafından olduğu söylenir ve olduğu söylenir.
  • Bir tür kümesindeki en çok kapsayan tür , kümedeki diğer tüm türleri kapsayan türdür. Diğer tüm türleri kapsayan tek bir tür yoksa, kümenin en çok kapsayan türü yoktur. Daha sezgisel bir ifadeyle, en çok kapsayan tür kümedeki "en büyük" türdür; diğer türlerin her birinin örtük olarak dönüştürülebileceği türdür.
  • Bir tür kümesindeki en çok kapsadığı tür , kümedeki diğer tüm türler tarafından kapsadığı tek türdür. Diğer tüm türler tarafından tek bir tür kapsanmazsa, kümenin en çok kapsanan türü yoktur. Daha sezgisel bir ifadeyle, en kapsamlı tür kümedeki "en küçük" türdür; diğer türlerin her birine örtük olarak dönüştürülebilen türdür.

10.5.4 Kullanıcı tanımlı örtük dönüştürmeler

bir ifadeden E türe T kullanıcı tanımlı örtük dönüştürme aşağıdaki gibi işlenir:

  • ve Stürlerini S₀T₀ belirleyin.

    • Türü varsa E , S bu tür olsun.
    • Veya null atanabilir değer türleriyseS, temel türlerine izin verin T ve Sᵢ bu türler olsun; aksi takdirde sırasıyla ve TᵢSᵢolarak Tᵢ izin verinS.T
    • Veya tür parametreleriyseSᵢ, etkin temel sınıflarına izin verin Tᵢ ve S₀ olun; aksi takdirde sırasıyla ve olarak izin verin T₀ ve S₀T₀olunSₓ.Tᵢ
  • Kullanıcı tanımlı dönüştürme işleçlerinin dikkate alınacağı tür Dkümesini bulun. Bu küme (varsa ve bir sınıf veya yapıysaS₀), temel sınıflarından S₀ (varsa ve bir sınıfsaS₀) ve S₀ (bir sınıf veya yapıysaT₀) oluşur T₀ . Bir tür, kümeye yalnızca kümeye D zaten dahil olan başka bir türe kimlik dönüştürmesi mevcut değilse eklenir.

  • Geçerli kullanıcı tanımlı ve kaldırılmış dönüştürme işleçleri kümesini bulun. U Bu küme, içindeki sınıflar veya yapılar tarafından bildirilen kullanıcı tanımlı ve kaldırılmış örtük dönüştürme işleçlerinden oluşur. Bu işleçler D , öğesini kapsayan E bir türden ile Tkapsadığı bir türe dönüştürülür. Boşsa U , dönüştürme tanımsız olur ve derleme zamanı hatası oluşur.

    • varsa ve içindeki işleçlerden S herhangi biri ' den US dönüştürüyorsa Sₓ , olurS.
    • Aksi takdirde, Sₓ içindeki işleçlerin Ubirleştirilmiş kaynak türleri kümesindeki en çok kapsayılan türdür. Tam olarak en çok kapsanan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • içindeki işleçlerin Tₓen özel hedef türünü Ubulun:

    • içindeki U işleçlerden herhangi biri öğesine TTₓ dönüştürülürse, olurT.
    • Aksi takdirde, Tₓ içindeki işleçlerin Ubirleştirilmiş hedef türleri kümesindeki en kapsayan türdür. Tam olarak en çok kapsayan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • En özel dönüştürme işlecini bulun:

    • 'den USₓöğesine dönüştürülen tam olarak bir kullanıcı tanımlı dönüştürme işleci içeriyorsaTₓ, bu en özel dönüştürme işlecidir.
    • Aksi takdirde, 'den'e USₓdönüştürülen tam olarak bir yükseltilmiş dönüştürme işleci içeriyorsaTₓ, bu en özel dönüştürme işlecidir.
    • Aksi takdirde, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • Son olarak, dönüştürmeyi uygulayın:

    • E türüne sahip Sₓdeğilse, 'den'e ESₓ standart bir örtük dönüştürme gerçekleştirilir.
    • en özel dönüştürme işleci, 'den'e SₓTₓdönüştürmek için çağrılır.
    • TₓdeğilseT, yerine standart bir örtük dönüştürme TₓT gerçekleştirilir.

Kullanıcı tanımlı bir örtük dönüştürme türü türünden S türüne T mevcutsa, türünden S türe Tkullanıcı tanımlı örtük dönüştürme mevcut olur.

10.5.5 Kullanıcı tanımlı açık dönüştürmeler

Bir ifadeden E türe T kullanıcı tanımlı açık dönüştürme aşağıdaki gibi işlenir:

  • ve Stürlerini S₀T₀ belirleyin.
    • Türü varsa E , S bu tür olsun.
    • Veya null atanabilir değer türleriyseS, temel türlerine izin verin T ve Sᵢ bu türler olsun; aksi takdirde sırasıyla ve TᵢSᵢolarak Tᵢ izin verinS.T
    • Veya tür parametreleriyseSᵢ, etkin temel sınıflarına izin verin Tᵢ ve S₀ olun; aksi takdirde sırasıyla ve olarak izin verin T₀ ve S₀T₀olunSᵢ.Tᵢ
  • Kullanıcı tanımlı dönüştürme işleçlerinin dikkate alınacağı tür Dkümesini bulun. Bu küme (varsa ve bir sınıf veya yapıysaS₀), temel sınıflarından S₀ (varsa ve bir sınıfsaS₀), S₀ (bir sınıf veya yapıysaT₀) ve temel sınıflarından T₀ (sınıf iseT₀) oluşur T₀ . Bir tür, kümeye yalnızca kümeye D zaten dahil olan başka bir türe kimlik dönüştürmesi mevcut değilse eklenir.
  • Geçerli kullanıcı tanımlı ve kaldırılmış dönüştürme işleçleri kümesini bulun. U Bu küme, içindeki sınıflar veya yapılar tarafından bildirilen kullanıcı tanımlı ve kaldırılmış örtük veya açık dönüştürme işleçlerinden D oluşur. Bu işleçler E tarafından kapsanan veya (varsa) tarafından S kapsanan veya kapsayan bir türe Tdönüştüren. Boşsa U , dönüştürme tanımsız olur ve derleme zamanı hatası oluşur.
  • içindeki işleçlerin Sₓen özel kaynak türünü Ubulun:
    • S varsa ve içindeki işleçlerden U herhangi biri ' den Sdönüştürüyorsa , Sₓ olur S.
    • Aksi takdirde, içindeki U işleçlerden herhangi biri öğesini kapsayan ESₓ türlerden dönüştürürse, bu işleçlerin birleştirilmiş kaynak türleri kümesinde en çok kapsanan türdür. En fazla kapsanan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
    • Aksi takdirde, Sₓ içindeki işleçlerin Ubirleştirilmiş kaynak türleri kümesindeki en kapsayan türdür. Tam olarak en çok kapsayan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • içindeki işleçlerin Tₓen özel hedef türünü Ubulun:
    • içindeki U işleçlerden herhangi biri öğesine TTₓ dönüştürülürse, olurT.
    • Aksi takdirde, içindeki U işleçlerden herhangi biri tarafından TTₓ kapsanan türlere dönüştürülürse, bu işleçlerin birleştirilmiş hedef türleri kümesinde en çok kapsanan türdür. Tam olarak en çok kapsayan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
    • Aksi takdirde, Tₓ içindeki işleçlerin Ubirleştirilmiş hedef türleri kümesinde en çok kapsanan türdür. En fazla kapsanan bir tür bulunamazsa, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • En özel dönüştürme işlecini bulun:
    • U, 'den SₓTₓöğesine dönüştüren tam olarak bir kullanıcı tanımlı dönüştürme işleci içeriyorsa, bu en özel dönüştürme işlecidir.
    • Aksi takdirde, 'den'e USₓdönüştürülen tam olarak bir yükseltilmiş dönüştürme işleci içeriyorsaTₓ, bu en özel dönüştürme işlecidir.
    • Aksi takdirde, dönüştürme belirsizdir ve derleme zamanı hatası oluşur.
  • Son olarak, dönüştürmeyi uygulayın:
    • türüne Esahip değilseSₓ, E'den 'ye Sₓ standart bir açık dönüştürme gerçekleştirilir.
    • kullanıcı tanımlı en özel dönüştürme işleci, 'den SₓTₓöğesine dönüştürmek için çağrılır.
    • TₓdeğilseT, için standart bir açık dönüştürme TₓT gerçekleştirilir.

Türünden türüne S kullanıcı tanımlı açık T dönüştürme mevcutsa, bir türden S türe Tkullanıcı tanımlı açık dönüştürme var olur.

10.6 Null atanabilir türleri içeren dönüştürmeler

10.6.1 Null Atanabilir Dönüştürmeler

Null atanabilir dönüştürmeler , null atanamayan değer türleri üzerinde çalışan önceden tanımlanmış dönüştürmelerin bu türlerdeki null atanabilir formlarla da kullanılmasına izin verir. Boş değer atanamayan bir değer türünden (§10.2.2, §10.2.3S§10.2.11, Tve §10.3.3) önceden tanımlanmış örtük veya açık dönüştürmelerin her biri için aşağıdaki null atanabilir dönüştürmeler vardır:

  • ile örtük veya açık dönüştürme S?T?
  • ile örtük veya açık dönüştürme ST?
  • 'den öğesine S?Taçık bir dönüştürme.

Null atanabilir dönüştürme, örtük veya açık dönüştürme olarak sınıflandırılır.

Bazı null atanabilir dönüştürmeler standart dönüştürmeler olarak sınıflandırılır ve kullanıcı tanımlı dönüştürmenin bir parçası olarak gerçekleşebilir. Özellikle, tüm örtük null atanabilir dönüştürmeler standart örtük dönüştürmeler (§10.4.2) olarak sınıflandırılır ve §10.4.3 gereksinimlerini karşılayan açık null atanabilir dönüştürmeler standart açık dönüştürmeler olarak sınıflandırılır.

'den S temel alınan dönüştürmeye T göre null atanabilir dönüştürmenin değerlendirilmesi aşağıdaki gibi devam eder:

  • Null atanabilir dönüştürme ' den ' S? e T?ise:
    • Kaynak değer null ise (HasValue özellik olur false), sonuç türündeki T?null değerdir.
    • Aksi takdirde, dönüştürme, 'den 'a ve ardından 'den S? 'a Stemel alınan dönüştürmenin ardından 'den ST 'a TT?sarmalama olarak değerlendirilir.
  • Null değer atanabilir dönüştürme 'den'e ST?ise dönüştürme, 'den 'a temel alınan dönüştürme ve ardından 'den ST 'a TT?sarmalama olarak değerlendirilir.
  • Null değer atanabilir dönüştürme 'den'e S?Tise, dönüştürme, 'den S? 'a S temel alınan dönüştürmeden STsonra öğesine doğru bir unwrapping olarak değerlendirilir.

10.6.2 Kaldırılan dönüşümler

Null atanamayan bir değer türünden null değer türüne S dönüştüren kullanıcı tanımlı dönüştürme işleci verildiğinde, T vardır. Bu kaldırılan dönüştürme işleci, öğesinden S?S öğesine kullanıcı tanımlı dönüştürme ve ardından öğesinden ST öğesine sarmalama TT?işlemiyle bir unwrapping gerçekleştirir, ancak null değerlemesi S? doğrudan null değere T?dönüştürülür. Kaldırılan dönüştürme işleci, temel alınan kullanıcı tanımlı dönüştürme işleciyle aynı örtük veya açık sınıflandırmaya sahiptir.

10.7 Anonim işlev dönüştürmeleri

10.7.1 Genel

anonymous_method_expression veya lambda_expression anonim işlev (§12.19) olarak sınıflandırılır. İfadenin türü yoktur, ancak örtük olarak uyumlu bir temsilci türüne dönüştürülebilir. Bazı lambda ifadeleri de örtük olarak uyumlu bir ifade ağacı türüne dönüştürülebilir.

Özellikle, anonim bir işlev F sağlanan bir temsilci türüyle D uyumludur:

  • bir anonymous_function_signature Fiçeriyorsa ve D aynı sayıda parametreye sahipseF.
  • bir anonymous_function_signatureF, D parametresi bir çıkış parametresi olmadığı sürece D herhangi bir türde sıfır veya daha fazla parametreye sahip olabilir.
  • Açıkça yazılan bir parametre listesi varsa F , içindeki D her parametre içinde karşılık gelen parametreyle F aynı değiştiricilere sahiptir ve içindeki ilgili parametre Farasında bir kimlik dönüştürmesi vardır.
  • Örtük olarak yazılan bir parametre listesi varsa F , D başvuru veya çıkış parametresi yoktur.
  • gövdesi F bir ifadeyse veD geçersiz dönüş türüne sahipse veyaF zaman uyumsuzsa ve D dönüş «TaskType» türüne (§15.14.1) sahipse, her parametresinde FDkarşılık gelen parametrenin türü verildiğinde gövdesiF, statement_expression (§13.7) olarak izin verilecek geçerli bir ifadedir (w.r.t §12).
  • gövdesi F bir bloksa veDgeçersiz dönüş türüne sahipse veyaF zaman uyumsuzsa ve D bir «TaskType» dönüş türüne sahipse, her parametresine F içinde Dkarşılık gelen parametrenin türü verildiğinde gövdesiF, hiçbir deyimin ifade belirtmediği geçerli bir bloktur (w.r.t return
  • F gövdesi bir ifadeyse ve ya zaman uyumsuz değilse ve F dönüş türü D değilse voidT zaman uyumluysa ve dönüş türü sahipse (F), her parametresine D içinde «TaskType»<T> karşılık gelen parametrenin türü verildiğinde, gövdesi örtük olarak F dönüşebilen geçerli bir ifadedir (bkz. D).
  • gövdesi F bir bloksa ve ya zamanFgeçersiz olmayan bir dönüş türüne DT zaman uyumsuzsa ve bir F dönüş türüne sahipse, her parametresine D içinde «TaskType»<T>karşılık gelen parametrenin türü verildiğinde gövdesi F geçerli bir deyim bloğudur (w.r.t D) ve her dönüş deyiminin örtük olarak dönüştürülebilir Fbir ifade belirttiği ulaşılamayan bir bitiş noktasıdır.

Örnek: Aşağıdaki örneklerde bu kurallar gösterilmektedir:

delegate void D(int x);
D d1 = delegate { };                         // Ok
D d2 = delegate() { };                       // Error, signature mismatch
D d3 = delegate(long x) { };                 // Error, signature mismatch
D d4 = delegate(int x) { };                  // Ok
D d5 = delegate(int x) { return; };          // Ok
D d6 = delegate(int x) { return x; };        // Error, return type mismatch

delegate void E(out int x);
E e1 = delegate { };                         // Error, E has an output parameter
E e2 = delegate(out int x) { x = 1; };       // Ok
E e3 = delegate(ref int x) { x = 1; };       // Error, signature mismatch

delegate int P(params int[] a);
P p1 = delegate { };                         // Error, end of block reachable
P p2 = delegate { return; };                 // Error, return type mismatch
P p3 = delegate { return 1; };               // Ok
P p4 = delegate { return "Hello"; };         // Error, return type mismatch
P p5 = delegate(int[] a)                     // Ok
{
    return a[0];
};
P p6 = delegate(params int[] a)              // Error, params modifier
{
    return a[0];
};
P p7 = delegate(int[] a)                     // Error, return type mismatch
{
    if (a.Length > 0) return a[0];
    return "Hello";
};

delegate object Q(params int[] a);
Q q1 = delegate(int[] a)                    // Ok
{
    if (a.Length > 0) return a[0];
    return "Hello";
};

son örnek

Örnek: Aşağıdaki örneklerde, türünde bağımsız değişken alan ve türünde Func<A,R>A bir değer döndüren bir işlevi temsil eden genel bir temsilci türü Rkullanılır:

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

Atamalarda

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 anonim işlevin parametre ve dönüş türleri, anonim işlevin atandığı değişkenin türünden belirlenir.

İlk atama anonim işlevi başarıyla temsilci türüne Func<int,int> dönüştürür, çünkü türü verildiğinde xintx + 1türüne örtük olarak dönüştürülebilir intgeçerli bir ifadedir.

Benzer şekilde, ikinci atama anonim işlevi başarıyla Func<int,double> temsilci türüne dönüştürür çünkü sonucu x + 1 (türü int) türüne doubleörtük olarak dönüştürülebilir.

Ancak, üçüncü atama derleme zamanı hatasıdır çünkü türü xdoubleverildiğinde x + 1 sonucu (türüdouble) türüne intörtük olarak dönüştürülemez.

Dördüncü atama, anonim zaman uyumsuz işlevi temsilci türüne Func<int, Task<int>> başarıyla dönüştürür çünkü sonucu x + 1 (türüint) örtük olarak dönüş inttürüne sahip olan zaman uyumsuz lambda'nın etkin dönüş türüne Task<int> dönüştürülebilir.

son örnek

Lambda ifadesi F , temsilci türüyle Expression<D> uyumluysa F bir ifade ağacı türüyle Duyumludur. Bu, anonim yöntemler için geçerli değildir, yalnızca lambda ifadeleri için geçerlidir.

Anonim işlevler aşırı yükleme çözümlemesini etkileyebilir ve tür çıkarımına katılabilir. Diğer ayrıntılar için bkz . §12.6 .

10.7.2 Temsilci türlerine anonim işlev dönüştürmelerinin değerlendirilmesi

Anonim işlevin temsilci türüne dönüştürülmesi, anonim işleve ve değerlendirme sırasında etkin olan yakalanan dış değişkenlerin (muhtemelen boş) kümesine başvuran bir temsilci örneği oluşturur. Temsilci çağrıldığında anonim işlevin gövdesi yürütülür. Gövdedeki kod, temsilci tarafından başvuruda bulunan yakalanan dış değişkenler kümesi kullanılarak yürütülür. Anonim bir yöntemi temsilci türüne dönüştürmek için alternatif söz dizimi olarak bir delegate_creation_expression (§12.8.17.5) kullanılabilir.

Anonim bir işlevden oluşturulan temsilcinin çağrı listesi tek bir girdi içerir. Temsilcinin tam hedef nesnesi ve hedef yöntemi belirtilmemiştir. Özellikle, temsilcinin hedef nesnesinin, null kapsayan işlev üyesinin değeri mi yoksa başka bir nesne mi olduğu thisbelirtilmez.

Aynı (büyük olasılıkla boş) yakalanan dış değişken örnekleri kümesiyle aynı temsilci türlerine benzer şekilde özdeş anonim işlevlerin aynı temsilci örneğini döndürmesine izin verilir (ancak gerekli değildir). Burada anlamsal olarak özdeş terimi, anonim işlevlerin yürütülmesinin her durumda aynı bağımsız değişkenlerle aynı etkileri üreteceği anlamına gelir. Bu kural, aşağıdaki gibi kodun iyileştirilmesine izin verir.

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 olarak aynı olduğundan, bir derleyicinin temsilcilerin aynı hedef yönteme başvurmasına izin verilir. Aslında, bir derleyicinin her iki anonim işlev ifadesinden de aynı temsilci örneğini döndürmesine izin verilir.

10.7.3 Lambda ifadesinin ifade ağacı türlerine dönüştürülmesi değerlendirmesi

Lambda ifadesinin bir ifade ağacı türüne dönüştürülmesi bir ifade ağacı (§8.6) oluşturur. Daha kesin olarak, lambda ifade dönüştürmesinin değerlendirilmesi, lambda ifadesinin yapısını temsil eden bir nesne yapısı oluşturur.

Her lambda ifadesi, ifade ağacı türlerine dönüştürülemez. Uyumlu bir temsilci türüne dönüştürme her zaman vardır, ancak uygulama tanımlı nedenlerle derleme zamanında başarısız olabilir.

Not: Lambda ifadesinin ifade ağacı türüne dönüştürülememesinin yaygın nedenleri şunlardır:

  • Blok gövdesi var
  • Değiştiriciye async sahiptir
  • Atama işleci içerir
  • Bir çıkış veya başvuru parametresi içerir
  • Dinamik olarak bağlı bir ifade içerir

son not

10.8 Yöntem grubu dönüştürmeleri

Bir yöntem grubundan (§12.2) uyumlu bir temsilci türüne (§20.4) örtük dönüştürme vardır. Bir D temsilci türüyse ve E bir yöntem grubu olarak sınıflandırılan bir ifadeyse, D aşağıda açıklandığı gibi parametresi türleriyle ve değiştiricileriyle EE eşleşen türleri ve değiştiricileri olan herhangi bir bağımsız değişken listesine (§12.6.4.2) normal biçiminde (§12.6.4.2) uygulanabilir en az bir yöntem içeriyorsa if ve only D ile uyumludur.

Bir yöntem grubundan E temsilci türüne D dönüştürmenin derleme zamanı uygulaması aşağıda açıklanmıştır.

  • Aşağıdaki değişikliklerle, formun Mbir yöntem çağrısına (§12.8.10.2) karşılık gelen tek bir yöntem E(A) seçilir:
    • Bağımsız değişken listesiA, her biri değişken olarak sınıflandırılan ve parameter_list karşılık gelen parametreninintürüne ve değiştiricisine out (ref, , veya D) sahip olan ifadelerin dynamiclistesidir; buna karşılık gelen ifadenin türü object yerine dynamictüründe olan parametreler dışında.
    • Kabul edilen aday yöntemleri yalnızca normal biçimlerinde geçerli olan ve isteğe bağlı parametreleri atlayan yöntemlerdir (§12.6.4.2). Bu nedenle, aday yöntemleri yalnızca genişletilmiş biçimlerinde uygulanıyorsa veya isteğe bağlı parametrelerinden bir veya daha fazlası içinde Dkarşılık gelen bir parametreye sahip değilse yoksayılır.
  • §12.8.10.2 algoritması olduğu kabul edilir.
  • Seçilen yöntem M bir örnek yöntemiyse, ile E ilişkilendirilmiş örnek ifadesi temsilcinin hedef nesnesini belirler.
  • Seçilen yöntem M bir örnek ifadesinde üye erişimiyle belirtilen bir uzantı yöntemiyse, bu örnek ifadesi temsilcinin hedef nesnesini belirler.
  • Dönüştürmenin sonucu, türündeki Dbir değerdir, yani seçili yönteme ve hedef nesneye başvuran bir temsilcidir.

Örnek: Aşağıda yöntem grubu dönüştürmeleri gösterilmektedir:

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

ataması d1 , yöntem grubunu F örtük olarak türünde D1bir değere dönüştürür.

ataması d2 , daha az türetilmiş (değişken karşıtı) parametre türlerine ve daha fazla türetilmiş (birlikte değişken) dönüş türüne sahip bir yönteme temsilci oluşturmanın nasıl mümkün olduğunu gösterir.

için atama d3 , yöntem geçerli değilse dönüştürmenin nasıl mevcut olmadığını gösterir.

ataması d4 , yöntemin normal biçiminde nasıl uygulanabilmesi gerektiğini gösterir.

ataması d5 , temsilci ve yöntemin parametre ve dönüş türlerinin yalnızca başvuru türleri için nasıl farklılık göstermesine izin verilip verilmeyeceği gösterir.

son örnek

Diğer tüm örtük ve açık dönüştürmelerde olduğu gibi, atama işleci belirli bir dönüştürmeyi açıkça gerçekleştirmek için kullanılabilir.

Örnek: Bu nedenle, örnek

object obj = new EventHandler(myDialog.OkClick);

bunun yerine yazılabilir

object obj = (EventHandler)myDialog.OkClick;

son örnek

Yöntem grubu dönüştürme, içinde Etür bağımsız değişkenlerini açıkça belirterek veya tür çıkarımı (§12.6.3) yoluyla genel bir yönteme başvurabilir. Tür çıkarımı kullanılırsa, çıkarım işleminde bağımsız değişken türleri olarak temsilcinin parametre türleri kullanılır. Temsilcinin dönüş türü çıkarım için kullanılmaz. Tür bağımsız değişkenlerinin belirtilip belirtilip çıkarılmadığı, yöntem grubu dönüştürme işleminin bir parçasıdır; bunlar, sonuçta elde edilen temsilci çağrıldığında hedef yöntemi çağırmak için kullanılan tür bağımsız değişkenleridir.

Örnek:

delegate int D(string s, int i);
delegate int E();

class X
{
    public static T F<T>(string s, T t) {...}
    public static T G<T>() {...}

    static void Main()
    {
        D d1 = F<int>;        // Ok, type argument given explicitly
        D d2 = F;             // Ok, int inferred as type argument
        E e1 = G<int>;        // Ok, type argument given explicitly
        E e2 = G;             // Error, cannot infer from return type
    }
}

son örnek

Yöntem grupları aşırı yükleme çözümlemesini etkileyebilir ve tür çıkarımına katılabilir. Diğer ayrıntılar için bkz . §12.6 .

Bir yöntem grubu dönüştürmesinin çalışma zamanı değerlendirmesi aşağıdaki gibi devam eder:

  • Derleme zamanında seçilen yöntem bir örnek yöntemiyse veya örnek yöntemi olarak erişilen bir uzantı yöntemiyse, temsilcinin hedef nesnesi ile Eilişkilendirilmiş örnek ifadesinden belirlenir:
    • Örnek ifadesi değerlendirilir. Bu değerlendirme özel duruma neden olursa, başka bir adım yürütülür.
    • Örnek ifadesi bir reference_type ise, örnek ifadesi tarafından hesaplanan değer hedef nesne olur. Seçilen yöntem bir örnek yöntemiyse ve hedef nesne ise null, bir System.NullReferenceException oluşturulur ve başka adım yürütülür.
    • Örnek ifadesi bir value_type ise, değeri bir nesneye dönüştürmek için bir kutulama işlemi (§10.2.9) gerçekleştirilir ve bu nesne hedef nesne olur.
  • Aksi takdirde, seçilen yöntem statik yöntem çağrısının bir parçasıdır ve temsilcinin hedef nesnesi şeklindedir null.
  • Temsilci türünün D temsilci örneği, derleme zamanında belirlenen yönteme bir başvuru ve yukarıda hesaplanan hedef nesneye başvuru ile aşağıdaki gibi elde edilir:
    • Dönüştürmenin bu başvuruları içeren mevcut bir temsilci örneğini kullanmasına izin verilir (ancak gerekli değildir).
    • Mevcut bir örnek yeniden kullanılmazsa yeni bir örnek oluşturulur (§20.5). Yeni örneği ayırmak için yeterli bellek yoksa, bir System.OutOfMemoryException oluşturulur. Aksi takdirde örnek verilen başvurularla başlatılır.