Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
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
int
long
dönüştürme örtük olduğundan, türündekiint
ifadeler örtük olarak türlong
olarak işlenebilir. Türünden türünelong
int
karşı 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
T
için veT
arasındaT
. - herhangi bir başvuru türü
T
için veT?
arasındaT
. - ile
object
arası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
t1
t2
türlerinin vet3
tümünün iki öğesi vardır: birint
ve ardından birstring
. Tanımlama grubu öğesi türleri, ,t4
vet5
'det6
olduğ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,t4
vet5
demett6
tü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:
sbyte
short
,int
,long
,float
, ,double
veyadecimal
. - Uygulamasından
byte
,short
,ushort
,int
, ,uint
,long
,ulong
,float
veyadouble
öğesine.decimal
- Kaynak:
short
int
,long
,float
,double
veyadecimal
. - Kaynak:
ushort
int
,uint
,long
,ulong
,float
, ,double
veyadecimal
. - Kaynaktan
int
long
,float
,double
veyadecimal
. - Kaynak:
uint
long
,ulong
,float
,double
veyadecimal
. - Kimden
long
yerinefloat
,double
veyadecimal
. - Kimden
ulong
yerinefloat
,double
veyadecimal
. - Kaynak:
char
ushort
,int
,uint
,long
,ulong
, ,float
,double
veyadecimal
. -
float
değerindendouble
değerine.
, , int
uint
veya long
ulong
ile float
arasında ve oradan veya long
oradan ulong
double
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.FormattableString
daha 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
object
herhangi birdynamic
. - sağlanan herhangi bir class_type'den
S
herhangi birT
türetilir.S
- sağlanan herhangi bir herhangi bir
S
uygularT
.S
- sağlanan herhangi bir interface_type'den
S
herhangi birT
türetilir.S
- Öğe türüne sahip bir array_type
S
öğe türüneSᵢ
sahip birT
Tᵢ
aşağıdakilerin tümü doğruysa:-
S
veT
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ürmesiS
T
olması 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_type
I
- 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 (HasValue
yanlış) 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 S
birI
kutulama sınıfı ile arabiriminiS_Boxing
uygulamayı 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ğeriS
kutulama işlemi artık ifadeninnew 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, deyimleriS 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üneS
sahiptir ve sağ işlenen olarak değer türüne sahip işleci kullananis
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
object
object
dönüştürülmesinden farklıdır. Örneğin, aşağıdakilerstruct 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
p
box
10 değerinip
verir. Bunun yerine birPoint
olarak bildirilmiş olsaydıclass
, 20 değeri çıkış olurdu çünküp
vebox
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 T
bir 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
vei
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ünestring
örtük dönüştürmeler aranır. için bir dönüştürme bulunur, ancak olarakstring
bulunmazint
.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_expression
long
değeri negatif değilse türündeki bir constant_expression türüneulong
dö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ınaC
,T
herhangi bir temel sınıfınaC
veT
tarafındanC
uygulanan herhangi bir arabirime kadar. - '
T
nin etkili arabirim kümesindeki bir interface_typeI
temel arabirimineT
kadar. - From'dan (§15.2.5
T
U
Not: Bir başvuru türü olduğu bilindiğinden
T
, kapsamındakiT
çalışma zamanı türüU
, derleme zamanında başvuru türü olarak bilinmeseU
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ınaC
,T
herhangi bir temel sınıfınaC
veT
tarafındanC
uygulanan herhangi bir arabirime kadar.Not:
C
,System.Object
veyaSystem.ValueType
türlerindenSystem.Enum
biri olacaktır (aksi takdirdeT
başvuru türü olarak bilinir). son not - '
T
nin etkili arabirim kümesindeki bir interface_typeI
temel arabirimineT
kadar.
Başvuru türü olmadığı bilinmeyen bir type_parameterT
için, türü parametresine T
bağımlı U
olan 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 T
iç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'denS
başvuru türüne.S₀
S₀
S
Çalışma zamanında dönüştürme, dönüştürme ile aynı şekildeS₀
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üneI
I₀
I₀
Çalışma zamanında, bir değer türüyseT
, 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 E
değ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, ,t2
vet4
t5
bildirimlerinin tümü geçerlidir. 'dent3
'anull
dönüştürme olmadığından bildirimiint
geçersiz. tanımlama grubut5
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:
sbyte
byte
,ushort
,uint
,ulong
veyachar
. - Kimden
byte
veya öğesine.sbyte
char
- Kaynak:
short
sbyte
,byte
,ushort
,uint
, ,ulong
veyachar
. - Kaynaktan
ushort
sbyte
,byte
,short
veyachar
. - Kaynak:
int
sbyte
,byte
,short
,ushort
,uint
, ,ulong
veyachar
. - Kaynak:
uint
sbyte
,byte
,short
,ushort
, ,int
veyachar
. - Kaynak:
long
sbyte
,byte
,short
,ushort
,int
, ,uint
,ulong
veyachar
. - Kaynak:
ulong
sbyte
,byte
,short
,ushort
,int
, ,uint
,long
veyachar
. - Kimden
char
yerinesbyte
,byte
veyashort
. - Kaynak:
float
sbyte
,byte
,short
,ushort
,int
,uint
, ,long
,ulong
,char
veyadecimal
. - Kaynak:
double
sbyte
,byte
,short
,ushort
,int
,uint
, ,long
,ulong
,char
,float
veyadecimal
. - Kaynak:
decimal
sbyte
,byte
,short
,ushort
,int
,uint
, ,long
,ulong
,char
,float
veyadouble
.
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 birSystem.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
- 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, birSystem.OverflowException
oluşturulur. - bir tamser türünden
float
veyadouble
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.
- İşlenenin değeri NaN veya sonsuzsa, bir
- İş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.
- denetlenen bir bağlamda dönüştürme aşağıdaki gibi devam eder:
- 'den değerine
double
float
double
dönüştürme için, değer enfloat
yakın değere yuvarlanir.double
Değer olarakfloat
temsil etmek için çok küçükse, sonuç değerle aynı işaretle sıfır olur. Değerindouble
büyüklüğü bir olarakfloat
temsil 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österimedecimal
dönüştürülür ve gerekirse en yakın sayıya yuvarlanir (decimal
).- Kaynak değer olarak temsil
decimal
etmek için çok küçükse, sonuç sıfır olur ve imzalı sıfır değerlerini destekliyorsadecimal
özgün değerin işaretini korur. - Kaynak değerin büyüklüğü , olarak
decimal
temsil 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.
- Kaynak değer olarak temsil
- veya
decimal
float
olandouble
decimal
bir dönüştürme için, değer endouble
yakın veyafloat
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ür
decimal
, sonsuzluk veya NaN değerlerini desteklemek için gerekli değildir, ancak bunu yapabilir; aralığı vefloat
aralığındandouble
küçük olabilir, ancak olması garanti edilmemektedir. Sonsuz veya NaN değeri olmayan ve değerinden küçükdecimal
bir aralığa sahip gösterimler içinfloat
, ya da hiçbir zaman sonsuz ya dadecimal
float
NaN olmayacak şekilde dönüştürmenindouble
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
,double
veyadecimal
herhangi bir enum_type. - herhangi bir enum_type ,
sbyte
byte
,short
, ,ushort
,int
,uint
, ,long
,ulong
char
float
double
veya .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
E
int
verildiğinde,E
'danbyte
'ye dönüştürme, 'danint
'e açık bir sayısal dönüştürme (byte
) olarak işlenir vebyte
'denE
'e dönüştürme, 'danbyte
'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_type
S
herhangi bir class_typeT
için temel sınıfıS
sağlanırT
. - Herhangi bir class_type
S
herhangi bir interface_typeT
S
sağlanan korumalı değildir ve sağlandığındaS
uygulanmaz.T
- Herhangi bir interface_type
S
herhangi bir , sağlananT
korumalı değildir veya sağlananT
uygularT
. - Sağlanan herhangi bir interface_type
S
interface_typeT
' denS
türetilmemiştir. - Öğe türüne sahip bir array_type
S
öğe türüneSᵢ
sahip birT
Tᵢ
aşağıdakilerin tümü doğruysa:-
S
veT
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ürmesiSystem.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 arabirimlerindenT[]
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üneT
açık başvuru dönüştürmesi varsa veS
'denT₀
öğesine bir kimlik dönüştürmesi varsa, başvuru türündenT₀
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 veT
varyans-dönüştürülebilirS
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 parametresiD<X₁...Xᵥ>
D<S₁...Sᵥ>
için:D<T₁...Tᵥ>
Xᵢ
D
- Sabitse
Xᵢ
,Sᵢ
ileTᵢ
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ırSᵢ
Tᵢ
. - Değişken karşıtıysa
Xᵢ
,Sᵢ
Tᵢ
aynı veya her iki başvuru türü de aynı olur.
- Sabitse
- 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 null
veya 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 T
açı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 E
değ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_value
I
non_nullable_value_type. - bir interface_type
I
non_nullable_value_type gelen ve variance_convertibleI₀
veyaI₀
'a dönüştürülebilir (I
) olduğu herhangi birI
I₀
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_typenull
veya 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
S
yürütülmesinden oluşur. Bu nedenle, deyimleriobject 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ınaT
T
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.I
T
- (§15.2.5olan
U
birT
T
sağlanana kadar.Not: Bir başvuru türü olduğu bilindiğinden
T
, kapsamındaT
, derleme zamanında başvuru türü olarak bilinmeseU
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ınaT
T
ve öğesine kadarC
.T
Not: C, ,
System.Object
veyaSystem.ValueType
türlerindenSystem.Enum
biri olacaktır (aksi takdirdeT
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ürmeI
T
yoktur. Bu dönüştürme, örtük bir kutulama dönüştürmesinden (§10.2.9)T
object
ve ardından açık bir başvuru dönüştürmesindenobject
I
oluşur. Çalışma zamanında, bir değer türüyseT
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üyseT
, dönüştürme açık bir başvuru dönüştürmesi olarak yürütülür. - (
U
) öğesine bağlıT
olanT
bir tür parametresindenU
sağlanana kadar. Çalışma zamanında, bir değer türü veT
başvuru türüyseU
dönüştürme, kutu açma dönüştürmesi olarak yürütülür. Çalışma zamanında, hem hemT
deU
değer türleriyseT
veU
mutlaka aynı türdeyse ve dönüştürme gerçekleştirilmediyse. Çalışma zamanında, bir başvuru türüyseT
,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
t
long
izin verilseydi, bunun döndüreceğiX<int>.F(7)
7L
kolayca 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 kutuluint
doğrudan 'a dönüştürülemeyeceğindenlong
ç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üneB
A
ve türündenB
B
türüneA
standart 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ü T
iç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₀
veT₀
farklı türlerdir. - veya
S₀
T₀
işleç bildiriminin gerçekleştiği sınıf veya yapı türüdür. - Ne
S₀
deT₀
interface_type. - Kullanıcı tanımlı dönüştürmeler hariç, 'den veya öğesine
S
T
T
S
dö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 S
T
dönüştürme, önce 'den S
X
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 nene de interface_type ise,'in tarafından olduğu söylenir ve 'ün kapsadığı söylenir. - bir ifadeden
türüne standart örtük dönüştürme ( §10.4.2 ) varsa veveya türü (varsa) interface_type ise,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
S
türleriniS₀
T₀
belirleyin.- Türü varsa
E
,S
bu tür olsun. - Veya null atanabilir değer türleriyse
S
, temel türlerine izin verinT
veSᵢ
bu türler olsun; aksi takdirde sırasıyla veTᵢ
Sᵢ
olarakTᵢ
izin verinS
.T
- Veya tür parametreleriyse
Sᵢ
, etkin temel sınıflarına izin verinTᵢ
veS₀
olun; aksi takdirde sırasıyla ve olarak izin verinT₀
veS₀
T₀
olunSₓ
.Tᵢ
- Türü varsa
Kullanıcı tanımlı dönüştürme işleçlerinin dikkate alınacağı tür
D
kümesini bulun. Bu küme (varsa ve bir sınıf veya yapıysaS₀
), temel sınıflarındanS₀
(varsa ve bir sınıfsaS₀
) veS₀
(bir sınıf veya yapıysaT₀
) oluşurT₀
. Bir tür, kümeye yalnızca kümeyeD
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çlerD
, öğesini kapsayanE
bir türden ileT
kapsadığı bir türe dönüştürülür. BoşsaU
, dönüştürme tanımsız olur ve derleme zamanı hatası oluşur.- varsa ve içindeki işleçlerden
S
herhangi biri ' denU
S
dönüştürüyorsaSₓ
, olurS
. - Aksi takdirde,
Sₓ
içindeki işleçlerinU
birleş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.
- varsa ve içindeki işleçlerden
içindeki işleçlerin
Tₓ
en özel hedef türünüU
bulun:- içindeki
U
işleçlerden herhangi biri öğesineT
Tₓ
dönüştürülürse, olurT
. - Aksi takdirde,
Tₓ
içindeki işleçlerinU
birleş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.
- içindeki
En özel dönüştürme işlecini bulun:
- 'den
U
Sₓ
öğ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
U
Sₓ
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.
- 'den
Son olarak, dönüştürmeyi uygulayın:
- E türüne sahip
Sₓ
değilse, 'den'eE
Sₓ
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ürmeTₓ
T
gerçekleştirilir.
- E türüne sahip
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 T
kullanı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
S
türleriniS₀
T₀
belirleyin.- Türü varsa
E
,S
bu tür olsun. - Veya null atanabilir değer türleriyse
S
, temel türlerine izin verinT
veSᵢ
bu türler olsun; aksi takdirde sırasıyla veTᵢ
Sᵢ
olarakTᵢ
izin verinS
.T
- Veya tür parametreleriyse
Sᵢ
, etkin temel sınıflarına izin verinTᵢ
veS₀
olun; aksi takdirde sırasıyla ve olarak izin verinT₀
veS₀
T₀
olunSᵢ
.Tᵢ
- Türü varsa
- Kullanıcı tanımlı dönüştürme işleçlerinin dikkate alınacağı tür
D
kümesini bulun. Bu küme (varsa ve bir sınıf veya yapıysaS₀
), temel sınıflarındanS₀
(varsa ve bir sınıfsaS₀
),S₀
(bir sınıf veya yapıysaT₀
) ve temel sınıflarındanT₀
(sınıf iseT₀
) oluşurT₀
. Bir tür, kümeye yalnızca kümeyeD
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çlerindenD
oluşur. Bu işleçlerE
tarafından kapsanan veya (varsa) tarafındanS
kapsanan veya kapsayan bir türeT
dönüştüren. BoşsaU
, 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üU
bulun:- S varsa ve içindeki işleçlerden
U
herhangi biri ' denS
dönüştürüyorsa ,Sₓ
olurS
. - Aksi takdirde, içindeki
U
işleçlerden herhangi biri öğesini kapsayanE
Sₓ
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çlerinU
birleş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.
- S varsa ve içindeki işleçlerden
- içindeki işleçlerin
Tₓ
en özel hedef türünüU
bulun:- içindeki
U
işleçlerden herhangi biri öğesineT
Tₓ
dönüştürülürse, olurT
. - Aksi takdirde, içindeki
U
işleçlerden herhangi biri tarafındanT
Tₓ
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çlerinU
birleş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.
- içindeki
- 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
U
Sₓ
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.
- U, 'den
- Son olarak, dönüştürmeyi uygulayın:
- türüne
E
sahip değilseSₓ
, E'den 'yeSₓ
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ürmeTₓ
T
gerçekleştirilir.
- türüne
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 T
kullanı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, T
ve §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
S
T?
- 'den öğesine
S?
T
açı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?
eT?
ise:- Kaynak değer null ise (
HasValue
özellik olurfalse
), sonuç türündekiT?
null değerdir. - Aksi takdirde, dönüştürme, 'den 'a ve ardından 'den
S?
'aS
temel alınan dönüştürmenin ardından 'denS
T
'aT
T?
sarmalama olarak değerlendirilir.
- Kaynak değer null ise (
- Null değer atanabilir dönüştürme 'den'e
S
T?
ise dönüştürme, 'den 'a temel alınan dönüştürme ve ardından 'denS
T
'aT
T?
sarmalama olarak değerlendirilir. - Null değer atanabilir dönüştürme 'den'e
S?
T
ise, dönüştürme, 'denS?
'aS
temel alınan dönüştürmedenS
T
sonra öğ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 S
T
öğesine sarmalama T
T?
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
F
içeriyorsa veD
aynı sayıda parametreye sahipseF
. - bir anonymous_function_signature
F
,D
parametresi bir çıkış parametresi olmadığı süreceD
herhangi bir türde sıfır veya daha fazla parametreye sahip olabilir. - Açıkça yazılan bir parametre listesi varsa
F
, içindekiD
her parametre içinde karşılık gelen parametreyleF
aynı değiştiricilere sahiptir ve içindeki ilgili parametreF
arası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 veD
dönüş«TaskType»
türüne (§15.14.1) sahipse, her parametresindeF
D
karşı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 veD
geçersiz dönüş türüne sahipse veyaF
zaman uyumsuzsa veD
bir«TaskType»
dönüş türüne sahipse, her parametresineF
içindeD
karşılık gelen parametrenin türü verildiğinde gövdesiF
, hiçbir deyimin ifade belirtmediği geçerli bir bloktur (w.r.treturn
-
F
gövdesi bir ifadeyse ve ya zaman uyumsuz değilse veF
dönüş türüD
değilsevoid
T
zaman uyumluysa ve dönüş türü sahipse (F
), her parametresineD
içinde«TaskType»<T>
karşılık gelen parametrenin türü verildiğinde, gövdesi örtük olarakF
dönüşebilen geçerli bir ifadedir (bkz.D
). - gövdesi
F
bir bloksa ve ya zamanF
geçersiz olmayan bir dönüş türüneD
T
zaman uyumsuzsa ve birF
dönüş türüne sahipse, her parametresineD
içinde«TaskType»<T>
karşılık gelen parametrenin türü verildiğinde gövdesiF
geçerli bir deyim bloğudur (w.r.tD
) ve her dönüş deyiminin örtük olarak dönüştürülebilirF
bir 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üR
kullanı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ğindex
int
x + 1
türüne örtük olarak dönüştürülebilirint
geç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ünedouble
örtük olarak dönüştürülebilir.Ancak, üçüncü atama derleme zamanı hatasıdır çünkü türü
x
double
verildiğindex + 1
sonucu (türüdouble
) türüneint
ö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ü sonucux + 1
(türüint
) örtük olarak dönüşint
türüne sahip olan zaman uyumsuz lambda'nın etkin dönüş türüneTask<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 D
uyumludur. 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 this
belirtilmez.
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 E
E
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
M
bir yöntem çağrısına (§12.8.10.2) karşılık gelen tek bir yöntemE(A)
seçilir:- Bağımsız değişken listesi
A
, her biri değişken olarak sınıflandırılan ve parameter_list karşılık gelen parametreninin
türüne ve değiştiricisineout
(ref
, , veyaD
) sahip olan ifadelerindynamic
listesidir; buna karşılık gelen ifadenin türüobject
yerinedynamic
tü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
D
karşılık gelen bir parametreye sahip değilse yoksayılır.
- Bağımsız değişken listesi
- §12.8.10.2 algoritması olduğu kabul edilir.
- Seçilen yöntem
M
bir örnek yöntemiyse, ileE
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
D
bir 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 grubunuF
örtük olarak türündeD1
bir 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 E
tü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
E
iliş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
, birSystem.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.
ECMA C# draft specification