8 Tür
8.1 Genel
C# dilinin türleri iki ana kategoriye ayrılır: başvuru türleri ve değer türleri. Hem değer türleri hem de başvuru türleri, bir veya daha fazla tür parametresi alan genel türler olabilir. Tür parametreleri hem değer türlerini hem de başvuru türlerini belirleyebilir.
type
: reference_type
| value_type
| type_parameter
| pointer_type // unsafe code support
;
pointer_type (§23.3) yalnızca güvenli olmayan kodda (§23) kullanılabilir.
Değer türleri, değer türlerinin değişkenlerinin verilerini doğrudan içermesi nedeniyle başvuru türlerinden farklılık gösterirken, başvuru türlerinin değişkenleri kendi verilerine başvuru depolar ve ikincisi nesne olarak bilinir. Başvuru türleriyle, iki değişkenin aynı nesneye başvurması ve bu nedenle bir değişkendeki işlemlerin diğer değişken tarafından başvuruda bulunan nesneyi etkilemesi mümkündür. Değer türleriyle, değişkenlerin her biri kendi veri kopyasına sahiptir ve biri üzerindeki işlemlerin diğerini etkilemesi mümkün değildir.
Not: Bir değişken bir başvuru veya çıkış parametresi olduğunda, kendi depolama alanı yoktur, ancak başka bir değişkenin depolamasına başvurur. Bu durumda ref veya out değişkeni, farklı bir değişken için değil, başka bir değişken için etkili bir diğer addır. son not
C#'nin tür sistemi, herhangi bir türde bir değerin nesne olarak ele alınabilmesi için birleştirilir. C# içindeki her tür doğrudan veya dolaylı olarak sınıf türünden object
türetilir ve object
tüm türlerin nihai temel sınıfıdır. Başvuru türlerinin değerleri yalnızca türü object
olarak görüntülenerek nesne olarak değerlendirilir. Değer türlerinin değerleri, kutulama ve kutu açma işlemleri (§8.3.13) gerçekleştirilerek nesne olarak değerlendirilir.
Kolaylık sağlamak için, bu belirtim boyunca, bazı kitaplık türü adları tam ad nitelikleri kullanılmadan yazılır. Daha fazla bilgi için §C.5 adresine bakın.
8.2 Başvuru türleri
8.2.1 Genel
Başvuru türü bir sınıf türü, arabirim türü, dizi türü, temsilci türü veya türdür dynamic
. Boş değer atanamayan her başvuru türü için, türün adına eklenerek ?
belirtilen karşılık gelen bir null atanabilir başvuru türü vardır.
reference_type
: non_nullable_reference_type
| nullable_reference_type
;
non_nullable_reference_type
: class_type
| interface_type
| array_type
| delegate_type
| 'dynamic'
;
class_type
: type_name
| 'object'
| 'string'
;
interface_type
: type_name
;
array_type
: non_array_type rank_specifier+
;
non_array_type
: value_type
| class_type
| interface_type
| delegate_type
| 'dynamic'
| type_parameter
| pointer_type // unsafe code support
;
rank_specifier
: '[' ','* ']'
;
delegate_type
: type_name
;
nullable_reference_type
: non_nullable_reference_type nullable_type_annotation
;
nullable_type_annotation
: '?'
;
pointer_type yalnızca güvenli olmayan kodda (§23.3) kullanılabilir. nullable_reference_type daha ayrıntılı olarak §8.9'da ele alınılmaktadır.
Başvuru türü değeri, türün bir örneğine başvurudur ve ikincisi nesne olarak bilinir. Özel değer null
tüm başvuru türleriyle uyumludur ve bir örneğin yokluğunu gösterir.
8.2.2 Sınıf türleri
Sınıf türü, veri üyeleri (sabitler ve alanlar), işlev üyeleri (yöntemler, özellikler, olaylar, dizin oluşturucular, işleçler, örnek oluşturucuları, sonlandırıcılar ve statik oluşturucular) ve iç içe türler içeren bir veri yapısı tanımlar. Sınıf türleri, türetilmiş sınıfların temel sınıfları genişletebildiği ve uzmanlaşabileceği bir mekanizma olan devralmayı destekler. Sınıf türlerinin örnekleri object_creation_expressionkullanılarak oluşturulur (§12.8.17.2).
Sınıf türleri §15'te açıklanmıştır.
Bazı önceden tanımlanmış sınıf türleri, aşağıdaki tabloda açıklandığı gibi C# dilinde özel bir anlama sahiptir.
Sınıf türü | Açıklama |
---|---|
System.Object |
Diğer tüm türlerin nihai temel sınıfı. Bkz . §8.2.3. |
System.String |
C# dilinin dize türü. Bkz . §8.2.5. |
System.ValueType |
Tüm değer türlerinin temel sınıfı. Bkz . §8.3.2. |
System.Enum |
Tüm enum türlerin temel sınıfı. Bkz. §19.5. |
System.Array |
Tüm dizi türlerinin temel sınıfı. Bkz . §17.2.2. |
System.Delegate |
Tüm delegate türlerin temel sınıfı. Bkz. §20.1. |
System.Exception |
Tüm özel durum türlerinin temel sınıfı. Bkz. §21.3. |
8.2.3 Nesne türü
object
Sınıf türü, diğer tüm türlerin nihai temel sınıfıdır. C# içindeki her tür doğrudan veya dolaylı olarak sınıf türünden object
türetilir.
anahtar sözcüğü object
, önceden tanımlanmış sınıfı System.Object
için bir diğer addır.
8.2.4 Dinamik tür
dynamic
gibi object
bir tür herhangi bir nesneye başvurabilir. türündeki dynamic
ifadelere işlemler uygulandığında, program çalıştırana kadar çözümlemeleri ertelenecek. Bu nedenle, işlem başvurulan nesneye yasal olarak uygulanamazsa, derleme sırasında hata verilmez. Bunun yerine, çalışma zamanında işlemin çözümü başarısız olduğunda bir özel durum oluşturulur.
Türü dynamic
daha ayrıntılı olarak §8.7 ve dinamik bağlama ise §12.3.1'de açıklanmıştır.
8.2.5 Dize türü
türü string
, doğrudan öğesinden object
devralınan korumalı bir sınıf türüdür. sınıfının örnekleri string
Unicode karakter dizelerini temsil eder.
Türün string
değerleri dize değişmez değerleri (§6.4.5.6) olarak yazılabilir.
anahtar sözcüğü string
, önceden tanımlanmış sınıfı System.String
için bir diğer addır.
8.2.6 Arabirim türleri
Arabirim bir sözleşme tanımlar. Arabirim uygulayan bir sınıf veya yapı, sözleşmesine uymalıdır. Bir arabirim birden çok temel arabirimden devralabilir ve bir sınıf veya yapı birden çok arabirim uygulayabilir.
Arabirim türleri §18'de açıklanmıştır.
8.2.7 Dizi türleri
Dizi, hesaplanan dizinler aracılığıyla erişilen sıfır veya daha fazla değişken içeren bir veri yapısıdır. Dizinin öğeleri olarak da adlandırılan bir dizideki değişkenlerin tümü aynı türdedir ve bu tür dizinin öğe türü olarak adlandırılır.
Dizi türleri §17'de açıklanmıştır.
8.2.8 Temsilci türleri
Temsilci, bir veya daha fazla yönteme başvuran bir veri yapısıdır. Örneğin yöntemler, bunlara karşılık gelen nesne örneklerine de başvurur.
Not: C veya C++ içindeki bir temsilcinin en yakın eşdeğeri bir işlev işaretçisidir, ancak işlev işaretçisi yalnızca statik işlevlere başvurabilirken, temsilci hem statik hem de örnek yöntemlerine başvurabilir. İkinci durumda, temsilci yalnızca yöntemin giriş noktasına bir başvuru değil, aynı zamanda yönteminin çağrılacağı nesne örneğine de başvuru depolar. son not
Temsilci türleri §20'de açıklanmıştır.
8.3 Değer türleri
8.3.1 Genel
Değer türü bir yapı türü veya numaralandırma türüdür. C# basit türler olarak adlandırılan önceden tanımlanmış yapı türleri kümesi sağlar. Basit türler anahtar sözcüklerle tanımlanır.
value_type
: non_nullable_value_type
| nullable_value_type
;
non_nullable_value_type
: struct_type
| enum_type
;
struct_type
: type_name
| simple_type
| tuple_type
;
simple_type
: numeric_type
| 'bool'
;
numeric_type
: integral_type
| floating_point_type
| 'decimal'
;
integral_type
: 'sbyte'
| 'byte'
| 'short'
| 'ushort'
| 'int'
| 'uint'
| 'long'
| 'ulong'
| 'char'
;
floating_point_type
: 'float'
| 'double'
;
tuple_type
: '(' tuple_type_element (',' tuple_type_element)+ ')'
;
tuple_type_element
: type identifier?
;
enum_type
: type_name
;
nullable_value_type
: non_nullable_value_type nullable_type_annotation
;
Başvuru türünün değişkenlerinden farklı olarak, değer türündeki bir değişken değeri yalnızca değer null
türü null atanabilir bir değer türündeyse (§8.3.12) içerebilir. Null değer atanamayan her değer türü için, aynı değer kümesinin yanı sıra değerini belirten karşılık gelen bir null atanabilir değer null
türü vardır.
Değer türündeki bir değişkene atama, atanmakta olan değerin bir kopyasını oluşturur. Bu, başvuru türündeki bir değişkene atamadan farklıdır ve başvuru tarafından tanımlanan nesneyi kopyalar ancak kopyalanmaz.
8.3.2 System.ValueType türü
Tüm değer türleri örtük olarak sınıfından class
System.ValueType
devralır object
. Herhangi bir türün bir değer türünden türetmesi mümkün değildir ve bu nedenle değer türleri örtük olarak mühürlenir (§15.2.2.3).
System.ValueType
Bunun kendisi bir value_type olmadığını unutmayın. Bunun yerine, tüm value_type otomatik olarak türetildiği bir class_type.
8.3.3 Varsayılan oluşturucular
Tüm değer türleri, varsayılan oluşturucu olarak adlandırılan bir genel parametresiz örnek oluşturucuyu örtük olarak bildirir. Varsayılan oluşturucu, değer türü için varsayılan değer olarak bilinen sıfırdan başlatılan bir örnek döndürür:
- Tüm simple_typeiçin varsayılan değer, tüm sıfırların bit deseni tarafından üretilen değerdir:
-
sbyte
, ,byte
,short
,ushort
,int
,uint
,long
veulong
için varsayılan değerdir0
. - için
char
varsayılan değer şeklindedir'\x0000'
. - için
float
varsayılan değer şeklindedir0.0f
. - için
double
varsayılan değer şeklindedir0.0d
. - için
decimal
varsayılan değerdir0m
(yani, 0 ölçeğindeki sıfır değeridir). - için
bool
varsayılan değer şeklindedirfalse
. -
E
için varsayılan değer türüne0
E
dönüştürülür.
-
-
bir struct_type için varsayılan değer, tüm değer türü alanlarını varsayılan değerlerine ve tüm başvuru türü alanlarını
null
değerine ayarlayarak üretilen değerdir. -
Bir nullable_value_type için varsayılan değer, özelliğinin
HasValue
false olduğu bir örnektir. Varsayılan değer, null atanabilir değer türünün null değeri olarak da bilinir. Böyle bir değerinValue
özelliğinin okunmaya çalışılması, türSystem.InvalidOperationException
özel durumunun (§8.3.12) olmasına neden olur.
Diğer tüm örnek oluşturucular gibi, bir değer türünün varsayılan oluşturucusunun işleci kullanılarak çağrılır new
.
Not: Verimlilik nedenleriyle, bu gereksinim aslında uygulamanın bir oluşturucu çağrısı oluşturmasını sağlamak için tasarlanmamıştır. Değer türleri için, varsayılan değer ifadesi (§12.8.21) varsayılan oluşturucuyu kullanarak aynı sonucu verir. son not
Örnek: Aşağıdaki kodda,
i
vej
değişkenlerik
sıfır olarak başlatılır.class A { void F() { int i = 0; int j = new int(); int k = default(int); } }
son örnek
Her değer türünün örtük olarak bir ortak parametresiz örnek oluşturucusunun olması nedeniyle, yapı türünün parametresiz oluşturucunun açık bir bildirimini içermesi mümkün değildir. Ancak yapı türünün parametreli örnek oluşturucuları (§16.4.9) bildirmesine izin verilir.
8.3.4 Yapı türleri
Yapı türü, sabitleri, alanları, yöntemleri, özellikleri, olayları, dizin oluşturucuları, işleçleri, örnek oluşturucularını, statik oluşturucuları ve iç içe yerleştirilmiş türleri bildirebilen bir değer türüdür. Yapı türlerinin bildirimi §16'da açıklanmıştır.
8.3.5 Basit türler
C# basit türler olarak adlandırılan önceden tanımlanmış struct
türler kümesi sağlar. Basit türler anahtar sözcükler aracılığıyla tanımlanır, ancak bu anahtar sözcükler, aşağıdaki tabloda açıklandığı gibi ad alanında struct
önceden tanımlanmış System
türler için yalnızca diğer adlardır.
Anahtar sözcük | Diğer ad türü |
---|---|
sbyte |
System.SByte |
byte |
System.Byte |
short |
System.Int16 |
ushort |
System.UInt16 |
int |
System.Int32 |
uint |
System.UInt32 |
long |
System.Int64 |
ulong |
System.UInt64 |
char |
System.Char |
float |
System.Single |
double |
System.Double |
bool |
System.Boolean |
decimal |
System.Decimal |
Basit bir tür bir yapı türüne diğer ad verdiği için, her basit türün üyeleri vardır.
Örnek:
int
içinde bildirilenSystem.Int32
üyeleri ve üyelerin öğesindenSystem.Object
devralınır ve aşağıdaki deyimlere izin verilir:int i = int.MaxValue; // System.Int32.MaxValue constant string s = i.ToString(); // System.Int32.ToString() instance method string t = 123.ToString(); // System.Int32.ToString() instance method
son örnek
Not: Basit türler, bazı ek işlemlere izin verdikleri için içindeki diğer yapı türlerinden farklıdır:
- Çoğu basit tür, değerlerin değişmez değerler (§6.4.5) yazılarak oluşturulmasına izin verir, ancak C# genel olarak yapı türlerinin değişmez değerleri için sağlama yapmaz. Örnek:
123
türünint
değişmez değeridir ve'a'
türününchar
değişmez değeridir. son örnek- bir ifadenin işlenenlerinin tümü basit tür sabitleri olduğunda, derleyicinin derleme zamanında ifadeyi değerlendirmesi mümkündür. Böyle bir ifade constant_expression (§12.23) olarak bilinir. Diğer yapı türleri tarafından tanımlanan işleçleri içeren ifadeler sabit ifadeler olarak kabul edilmez
- Bildirimler aracılığıyla
const
, basit türlerin sabitlerini bildirmek mümkündür (§15.4). Diğer yapı türlerinin sabitlerine sahip olmak mümkün değildir, ancak benzer bir etki statik salt okunur alanlar tarafından sağlanır.- Basit türleri içeren dönüştürmeler, diğer yapı türleri tarafından tanımlanan dönüştürme işleçlerinin değerlendirilmesine katılabilir, ancak kullanıcı tanımlı dönüştürme işleci hiçbir zaman başka bir kullanıcı tanımlı dönüştürme işlecinin (§10.5.3) değerlendirmesine katılamıyor.
bitiş notunu seçin.
8.3.6 Integral türleri
C# dokuz tam sayı türünü destekler: sbyte
, byte
, short
, ushort
, int
, , uint
, long
ulong
ve char
. İntegral türleri aşağıdaki değer boyutlarına ve aralıklarına sahiptir:
- türü
sbyte
, 'den-128
127
değerine (dahil) sahip imzalı 8 bitlik tamsayıları temsil eder. - türü,
byte
'den0
255
değerine (dahil) kadar olan işaretsiz 8 bitlik tamsayıları temsil eder. - türü,
short
'den-32768
32767
değerine (dahil) sahip imzalı 16 bit tamsayıları temsil eder. - türü,
ushort
'den0
65535
değerine (dahil) kadar olan işaretsiz 16 bit tamsayıları temsil eder. - türü,
int
'den-2147483648
2147483647
değerine (dahil) sahip imzalı 32 bit tamsayıları temsil eder. - türü
uint
, 'den0
4294967295
değerine (dahil) kadar olan işaretsiz 32 bit tamsayıları temsil eder. - türü,
long
'den-9223372036854775808
9223372036854775807
değerine (dahil) sahip imzalı 64 bit tamsayıları temsil eder. - türü,
ulong
'den0
18446744073709551615
değerine (dahil) sahip işaretsiz 64 bit tamsayıları temsil eder. - türü,
char
'den0
65535
değerine (dahil) kadar olan işaretsiz 16 bit tamsayıları temsil eder. Türü için olası değerlerchar
kümesi Unicode karakter kümesine karşılık gelir.Not: ile aynı gösterime
char
sahip olsa daushort
, bir tür üzerinde izin verilen tüm işlemlere diğerinde izin verilmez. son not
tüm imzalı integral türleri, ikinin tamamlayıcı biçimi kullanılarak temsil edilir.
integral_type birli ve ikili işleçler her zaman §12.4.7'de ayrıntılı olarak açıklandığı gibi imzalı 32 bit duyarlık, imzasız 32 bit duyarlık, imzalı 64 bit duyarlık veya işaretsiz 64 bit duyarlık ile çalışır.
Türü char
bir integral türü olarak sınıflandırılır, ancak iki şekilde diğer integral türlerinden farklıdır:
- Diğer türlerden türe
char
önceden tanımlanmış örtük dönüştürme yoktur. Özellikle, vebyte
türleri türü kullanılarakushort
tam olarak temsil edilebilir değer aralıklarına sahip olsachar
da, sbayt, bayttan örtük dönüştürmeler veyaushort
char
mevcut değildir. - Türün
char
sabitleri character_literals veya integer_literals olarak yazı tipi karakteri ile birlikte yazılmalıdır.
Örnek:
(char)10
ile'\x000A'
aynıdır. son örnek
checked
ve unchecked
işleçleri ve deyimleri, tamsayı türü aritmetik işlemler ve dönüştürmeler (§12.8.20) için taşma denetimini denetlemek için kullanılır. Bir checked
bağlamda, taşma bir derleme zamanı hatası oluşturur veya bir System.OverflowException
oluşturulmasına neden olur. Bağlamda unchecked
taşmalar yoksayılır ve hedef türe sığmayan yüksek sıralı bitler atılır.
8.3.7 Kayan nokta türleri
C# iki kayan nokta türünü destekler: float
ve double
.
float
ve double
türleri, aşağıdaki değer kümelerini sağlayan 32 bit tek duyarlıklı ve 64 bit çift duyarlıklı IEC 60559 biçimleri kullanılarak temsil edilir:
- Pozitif sıfır ve negatif sıfır. Çoğu durumda pozitif sıfır ve negatif sıfır, basit sıfır değeriyle aynı şekilde davranır, ancak bazı işlemler ikisi arasında ayrım (§12.10.3) gerçekleştirir.
- Pozitif sonsuzluk ve negatif sonsuzluk. Sonsuzlar, sıfır olmayan bir sayıyı sıfıra bölme gibi işlemler tarafından üretilir.
Örnek:
1.0 / 0.0
pozitif sonsuzluk verir ve–1.0 / 0.0
negatif sonsuzluk verir. son örnek - Sayı Olmayan değeri, genellikle NaN olarak kısaltılır. NaN'ler, sıfırı sıfıra bölme gibi geçersiz kayan nokta işlemleriyle oluşturulur.
- Formun sıfır olmayan değerlerinin sonlu kümesi × m × 2e, burada s 1 veya −1, m ve e ise belirli kayan nokta türüne göre belirlenir: için, 0< 2²⁴ ve −149 ≤ < ≤ 104 ve için, 0
double
< 2⁵³ ve −1075 ≤ < ≤ 970. Normalleştirilmiş kayan noktalı sayılar geçerli sıfır olmayan değerler olarak kabul edilir. C# uyumlu bir uygulamanın normalleştirilmiş kayan nokta sayılarını desteklemesini gerektirmez veya yasaklamaz.
Bu float
tür, yaklaşık 1,5 × 10⁻⁴⁵ ile 3,4 × 10³⁸ arasındaki değerleri 7 basamaklı duyarlıkla temsil edebilir.
Bu double
tür, yaklaşık 5,0 × 10⁻³²⁴ ile 1,7 × 10³⁰⁸ arasında 15-16 basamaklı bir duyarlıkla değerleri temsil edebilir.
İkili işlecin işlenenlerinden biri kayan nokta türündeyse, §12.4.7'de ayrıntılı olarak açıklandığı gibi standart sayısal yükseltmeler uygulanır ve işlem veya float
duyarlıkla double
gerçekleştirilir.
Atama işleçleri de dahil olmak üzere kayan nokta işleçleri hiçbir zaman özel durum oluşturmaz. Bunun yerine, olağanüstü durumlarda kayan nokta işlemleri aşağıda açıklandığı gibi sıfır, sonsuz veya NaN üretir:
- Kayan nokta işleminin sonucu, hedef biçimde en yakın temsil edilebilir değere yuvarlanir.
- Kayan nokta işleminin sonucunun büyüklüğü hedef biçim için çok küçükse, işlemin sonucu pozitif sıfır veya negatif sıfır olur.
- Kayan nokta işleminin sonucunun büyüklüğü hedef biçim için çok büyükse, işlemin sonucu pozitif sonsuz veya negatif sonsuz olur.
- Kayan nokta işlemi geçersizse, işlemin sonucu NaN olur.
- Kayan nokta işleminin işlenenlerinden biri veya her ikisi de NaN ise, işlemin sonucu NaN olur.
Kayan nokta işlemleri, işlemin sonuç türünden daha yüksek hassasiyetle gerçekleştirilebilir. Kayan nokta türündeki bir değeri türünün tam duyarlığıyla zorlamak için açık bir atama (§12.9.7) kullanılabilir.
Örnek: Bazı donanım mimarileri, türünden daha büyük aralık ve duyarlık ile "genişletilmiş" veya "uzun çift" kayan
double
nokta türünü destekler ve bu daha yüksek duyarlık türünü kullanarak tüm kayan nokta işlemlerini örtük olarak gerçekleştirir. Yalnızca performans açısından aşırı maliyetle bu tür donanım mimarileri daha az duyarlıkla kayan nokta işlemleri gerçekleştirmek için yapılabilir ve hem performans hem de duyarlık kaybı için bir uygulama gerektirmek yerine, C# tüm kayan nokta işlemleri için daha yüksek bir duyarlık türü kullanılmasına izin verir. Daha kesin sonuçlar sunmanın dışında, bu nadiren ölçülebilir etkilere sahiptir. Ancak, çarpımın aralığın dışındax * y / z
bir sonuç ürettiği, ancak sonraki bölmenin geçici sonucu aralığa geridouble
getirdiği formdouble
ifadelerinde, ifadenin daha yüksek aralık biçiminde değerlendirildiği gerçeği sonsuzluk yerine sonlu bir sonucun üretilmesine neden olabilir. son örnek
8.3.8 Ondalık türü
Tür decimal
, finansal ve parasal hesaplamalar için uygun olan 128 bitlik bir veri türüdür. Tür, decimal
en az -7,9 × 10⁻²⁸ ile 7,9 × 10²⁸ aralığındaki değerleri en az 28 basamaklı duyarlıkla temsil edebilir.
Türün decimal
sonlu değer kümesi(–1)v × c × 10⁻e biçimindedir, burada v işareti 0 veya 1, katsayı c 0 ≤ c<Cmax tarafından verilir ve ölçek e, Emin ≤ e ≤ Emax şeklindedir; burada Cmax en az 1 × 10²⁸, Emin ≤ 0, ve Emax ≥ 28. Türün decimal
imzalı sıfırları, sonsuzlukları veya NaN'leri desteklemesi şart değildir.
A decimal
, on üssüyle ölçeklendirilmiş bir tamsayı olarak temsil edilir.
decimal
değerinden küçük 1.0m
mutlak değere sahip s için, değer en az 28. ondalık basamayı tam olarak gösterir.
decimal
değerinden büyük veya buna eşit mutlak değere 1.0m
sahip s için değer en az 28 basamağı tam olarak belirtir. ve float
veri türlerinin double
aksine, gibi 0.1
ondalık kesirli sayılar tam olarak ondalık gösterimde gösterilebilir.
float
ve double
gösterimlerinde, bu tür sayılar genellikle sonlandırıcı olmayan ikili genişletmelere sahiptir ve bu da bu gösterimleri yuvarlama hatalarına daha açık hale getirir.
İkili işlecin decimal
işlenenlerinden biri türündeyse, §12.4.7'de ayrıntılı olarak açıklandığı gibi standart sayısal yükseltmeler uygulanır ve işlem duyarlıkla double
gerçekleştirilir.
Tür decimal
değerleri üzerindeki bir işlemin sonucu, tam sonucun hesaplanmasından (her işleç için tanımlandığı gibi ölçeğin korunması) ve ardından gösterimi sığdırmak için yuvarlamanın sonucudur. Sonuçlar en yakın temsil edilebilir değere yuvarlanıp, bir sonuç iki temsil edilebilir değere eşit olarak yakın olduğunda, en az önemli basamak konumunda çift sayıya sahip olan değere (bu "bankacı yuvarlama" olarak bilinir) yuvarlanir. Yani, sonuçlar en az 28. ondalık basamayı gösterir. Yuvarlamanın sıfır olmayan bir değerden sıfır değeri üretebileceğini unutmayın.
Aritmetik bir decimal
işlem, büyüklüğü biçim için decimal
çok büyük olan bir sonuç üretirse, bir System.OverflowException
oluşturulur.
Türün decimal
duyarlığı daha yüksektir, ancak kayan nokta türlerinden daha küçük bir aralığa sahip olabilir. Bu nedenle, kayan nokta türlerinden 'a decimal
dönüştürmeler taşma özel durumları üretebilir ve kayan decimal
nokta türlerine dönüştürmeler duyarlık veya taşma özel durumlarının kaybına neden olabilir. Bu nedenlerden dolayı, kayan nokta türleri ile decimal
arasında örtük dönüştürme yoktur ve açık atamalar olmadan, kayan nokta ve decimal
işlenenler aynı ifadede doğrudan karıştırıldığında derleme zamanı hatası oluşur.
8.3.9 Bool türü
türü Boole bool
mantıksal miktarlarını temsil eder. Türün bool
olası değerleri ve true
şeklindedirfalse
. temsili false
§8.3.3'te açıklanmıştır. gösterimi true
belirtilmemiş olsa da, ile aynısından farklı false
olacaktır.
ve diğer değer türleri arasında bool
standart dönüştürme yoktur. Özellikle, bool
tür ayrıdır ve integral türlerinden ayrıdır, tamser değer yerine bir bool
değer kullanılamaz ve tam tersi de geçerlidir.
Not: C ve C++ dillerinde sıfır integral veya kayan nokta değeri ya da null işaretçi Boole değerine
false
, sıfır olmayan integral veya kayan nokta değerine dönüştürülebilir ya da null olmayan bir işaretçi Boole değerinetrue
dönüştürülebilir. C# dilinde bu tür dönüştürmeler, bir integral veya kayan nokta değerini açıkça sıfırla karşılaştırarak veya nesne başvurusunull
açıkça ile karşılaştırılarak gerçekleştirilir. son not
8.3.10 Numaralandırma türleri
Numaralandırma türü, adlandırılmış sabitleri olan ayrı bir türdür. Her sabit listesi türü, , byte
, , sbyte
short
, ushort
, int
uint
veya long
olacak ulong
temel bir türe sahiptir. Numaralandırma türünün değer kümesi, temel alınan türün değer kümesiyle aynıdır. Numaralandırma türünün değerleri adlandırılmış sabitlerin değerleriyle sınırlı değildir. Numaralandırma türleri, numaralandırma bildirimleri (§19.2) aracılığıyla tanımlanır.
8.3.11 Tanımlama Grubu türleri
Tanımlama grubu türü, isteğe bağlı adlara ve tek tek türlere sahip sıralı, sabit uzunlukta bir değer dizisini temsil eder. Bir tanımlama grubu türündeki öğelerin sayısı, onun arity değeri olarak adlandırılır. Tanımlama grubu türü n ≥ 2 ile yazılır (T1 I1, ..., Tn In)
ve burada tanımlayıcılar I1...In
isteğe bağlı tanımlama grubu öğe adlarıdır.
Bu söz dizimi, türü ile yapılandırılmış bir türün T1...Tn
System.ValueTuple<...>
kısaltmasıdır. Bu, iki ile yedi arasında (dahil) herhangi bir demet türünü doğrudan ifade edebilen bir dizi genel yapı türü olacaktır.
Herhangi bir System.ValueTuple<...>
tanımlama grubu türünün arlığına karşılık gelen sayıda tür parametresiyle doğrudan eşleşen bir bildirim olması gerekmez. Bunun yerine, değeri yediden büyük olan demetler, tanımlama grubu öğelerine ek olarak, başka System.ValueTuple<T1, ..., T7, TRest>
bir tür Rest
kullanılarak kalan öğelerin iç içe değerini içeren bir System.ValueTuple<...>
alana sahip olan genel bir yapı türüyle temsil edilir. Bu tür iç içe yerleştirme, örneğin bir Rest
alanın varlığı yoluyla çeşitli şekillerde gözlemlenebilir. Yalnızca tek bir ek alanın gerekli olduğu durumlarda genel yapı türü System.ValueTuple<T1>
kullanılır; bu tür kendi içinde bir tanımlama grubu türü olarak kabul edilmez. Yediden fazla ek alanın gerekli olduğu durumlarda özyinelemeli System.ValueTuple<T1, ..., T7, TRest>
olarak kullanılır.
Bir tanımlama grubu türü içindeki öğe adları ayrı olmalıdır. formunItemX
X
, bir tanımlama grubu öğesinin konumunu temsil edebilen başlatılmamış ondalık basamaklardan oluşan0
herhangi bir dizi olduğu bir tanımlama grubu öğesi adı, yalnızca tarafından X
belirtilen konumda izin verilir.
İsteğe bağlı öğe adları türlerde ValueTuple<...>
gösterilmez ve tanımlama grubu değerinin çalışma zamanı gösteriminde depolanmaz. Kimlik dönüştürmeleri (§10.2.2) öğe türlerinin kimlik dönüştürülebilir dizilerine sahip tanımlama kümeleri arasında bulunur.
new
§12.8.17.2 işleci tanımlama grubu türü söz dizimi new (T1, ..., Tn)
ile uygulanamaz. Tanımlama grubu değerleri tanımlama grubu ifadelerinden (§12.8.6) veya işleci doğrudan öğesinden new
oluşturulan bir türe uygulanarak ValueTuple<...>
oluşturulabilir.
Tanımlama grubu öğeleri, , Item1
vb. adlarına Item2
sahip genel alanlardır ve bir tanımlama grubu değeri (§12.8.7) üzerindeki üye erişimi aracılığıyla erişilebilir. Ayrıca, tanımlama grubu türünün belirli bir öğe için bir adı varsa, söz konusu öğeye erişmek için bu ad kullanılabilir.
Not: Büyük tanımlama grupları iç içe
System.ValueTuple<...>
değerlerle temsil edilse bile, her tanımlama grubu öğesine konumunaItem...
karşılık gelen adla doğrudan erişilebilir. son not
Örnek: Aşağıdaki örnekler verilmiştir:
(int, string) pair1 = (1, "One"); (int, string word) pair2 = (2, "Two"); (int number, string word) pair3 = (3, "Three"); (int Item1, string Item2) pair4 = (4, "Four"); // Error: "Item" names do not match their position (int Item2, string Item123) pair5 = (5, "Five"); (int, string) pair6 = new ValueTuple<int, string>(6, "Six"); ValueTuple<int, string> pair7 = (7, "Seven"); Console.WriteLine($"{pair2.Item1}, {pair2.Item2}, {pair2.word}");
,
pair1
vepair2
için tanımlama grubu türleripair3
, tanımlama grubu türü öğelerinin bazıları veya tümü için adlarla birlikte geçerlidir.Adların
pair4
ve konumlarının eşleşmesi nedeniyle için tanımlama grubu türüItem1
geçerlidir, ancak adlarItem2
vepair5
Item2
eşleşmediğinden için tanımlama grubu türüneItem123
izin verilmez.ve
pair6
bildirimleripair7
, tanımlama grubu türlerinin formunValueTuple<...>
oluşturulmuş türleriyle değiştirilebilir olduğunu ve işlecinenew
ikinci söz dizimiyle izin verildiğini gösterir.Son satır, tanımlama grubu öğelerine hem konumlarına karşılık gelen adla hem de türünde varsa ilgili tanımlama grubu öğesi adına göre erişilebileceğini
Item
gösterir. son örnek
8.3.12 Null değer türleri
Null atanabilir bir değer türü, temel alınan türün tüm değerlerini ve ek bir null değeri temsil edebilir. Null atanabilir bir değer türü yazılır T?
; burada T
temel alınan türdür. Bu söz dizimi için System.Nullable<T>
kısaltmadır ve iki form birbirinin yerine kullanılabilir.
Buna karşılık, boş değer atanamayan bir değer türü, ve kısaltması System.Nullable<T>
T?
(herhangi biri T
için) dışında herhangi bir değer türü, ayrıca null değer türü olmayan bir değer türü (yani değer türü kısıtlaması olan herhangi bir tür parametresi (§15.2.5)) olarak kısıtlanan herhangi bir tür parametresidir. türü System.Nullable<T>
için T
değer türü kısıtlamasını belirtir. Bu, null atanabilir bir değer türünün temel alınan türünün boş değer atanamayan herhangi bir değer türü olabileceği anlamına gelir. Null atanabilir bir değer türünün temel türü, null atanabilir bir değer türü veya başvuru türü olamaz. Örneğin, int??
geçersiz bir türdür. Null atanabilir başvuru türleri §8.9 kapsamındadır.
Null atanabilir bir değer türünün T?
örneği iki genel salt okunur özelliğe sahiptir:
-
HasValue
Türün özelliğibool
-
Value
Türün özelliğiT
Örneğin HasValue
true
null olmayan olduğu söylenir. Null olmayan bir örnek bilinen bir değer içerir ve Value
bu değeri döndürür.
örneğinin HasValue
false
null olduğu söylenir. Null örnek tanımlanmamış bir değere sahiptir. Null örneğinin Value
okunmaya çalışılması, bir System.InvalidOperationException
atılması neden olur. Null atanabilir bir örneğin Value özelliğine erişme işlemi, unwrapping olarak adlandırılır.
Varsayılan oluşturucuya ek olarak, her null atanabilir değer türünün T?
türünde T
tek bir parametresi olan bir ortak oluşturucu vardır. türünde x
bir değer T
verilip formun oluşturucu çağrısı
new T?(x)
, özelliğinin T?
olduğu Value
null olmayan bir örneğini x
oluşturur. Belirli bir değer için null değer türünün null olmayan bir örneğini oluşturma işlemi sarmalama olarak adlandırılır.
Örtük dönüştürmeler değişmez değerden (§10.2.7T
T?
Null atanabilir değer türü T?
arabirim uygulamaz (§18). Özellikle bu, temel alınan türün T
uyguladığı hiçbir arabirimi uygulamadığı anlamına gelir.
8.3.13 Kutulama ve kutu açma
Kutulama ve kutu açma kavramı, bir value_typeobject
köprü sağlar. Kutulama ve kutu açma, herhangi bir türdeki bir değerin sonunda olarak işlenebileceği tür sisteminin birleşik bir object
görünümünü etkinleştirir.
Boks , §10.2.9'da daha ayrıntılı olarak açıklanmıştır ve kutu açma özelliği ise §10.3.7'de açıklanmıştır.
8.4 Yapılı türler
8.4.1 Genel
Genel tür bildirimi, tür bağımsız değişkenlerini uygulayarak birçok farklı tür oluşturmak için "şema" olarak kullanılan ilişkisiz bir genel türü tek başına belirtir. Tür bağımsız değişkenleri, genel türün adının hemen ardından açılı ayraçlar (<
ve >
) içinde yazılır. En az bir tür bağımsız değişkeni içeren bir tür, yapılı tür olarak adlandırılır. Yapıtlı tür, dildeki bir tür adının görüntülenebildiği çoğu yerde kullanılabilir. İlişkisiz genel tür yalnızca bir typeof_expression içinde kullanılabilir (§12.8.18).
Yapılandırılmış türler, ifadelerde basit adlar (§12.8.4) veya üyeye erişirken (§12.8.7) de kullanılabilir.
Bir namespace_or_type_name değerlendirildiğinde, yalnızca doğru tür parametresi sayısına sahip genel türler dikkate alınır. Bu nedenle, türlerde farklı sayıda tür parametresi olduğu sürece, farklı türleri tanımlamak için aynı tanımlayıcıyı kullanmak mümkündür. Bu, aynı programdaki genel ve genel olmayan sınıfları karıştırırken kullanışlıdır.
Örnek:
namespace Widgets { class Queue {...} class Queue<TElement> {...} } namespace MyApplication { using Widgets; class X { Queue q1; // Non-generic Widgets.Queue Queue<int> q2; // Generic Widgets.Queue } }
son örnek
namespace_or_type_name üretimlerinde ad araması için ayrıntılı kurallar §7.8'de açıklanmıştır. Bu üretimlerdeki belirsizliklerin çözümü §6.2.5'te açıklanmıştır. Bir type_name , tür parametrelerini doğrudan belirtmese bile, yapılı bir türü tanımlayabilir. Bu durum, bir türün genel class
bir bildirimin içinde iç içe geçtiği ve içeren bildirimin örnek türünün ad araması (§15.3.9.7) için örtük olarak kullanıldığı durumlarda oluşabilir.
Örnek:
class Outer<T> { public class Inner {...} public Inner i; // Type of i is Outer<T>.Inner }
son örnek
Sabit listesi olmayan bir tür unmanaged_type (§8.8) olarak kullanılmamalıdır.
8.4.2 Tür bağımsız değişkenleri
Tür bağımsız değişken listesindeki her bağımsız değişken yalnızca bir türdür.
type_argument_list
: '<' type_arguments '>'
;
type_arguments
: type_argument (',' type_argument)*
;
type_argument
: type
| type_parameter nullable_type_annotation?
;
Her tür bağımsız değişkeni, ilgili tür parametresindeki (§15.2.5) kısıtlamaları karşılar. Null atanabilirliği tür parametresinin null atanabilirliğiyle eşleşmeyen bir başvuru türü bağımsız değişkeni kısıtlamayı karşılar; ancak bir uyarı verilebilir.
8.4.3 Açık ve kapalı türler
Tüm türler açık türler veya kapalı türler olarak sınıflandırılabilir. Açık tür, tür parametrelerini içeren bir türdür. Daha açık belirtmek gerekirse:
- Tür parametresi açık bir tür tanımlar.
- Dizi türü, yalnızca öğe türü açık bir türse açık bir türdür.
- Yalnızca türü bağımsız değişkenlerinden biri veya daha fazlası açık bir türse, yapılı tür açık bir türdür. İç içe yerleştirilmiş bir tür, yalnızca bir veya daha fazla tür bağımsız değişkeni veya içeren türlerin tür bağımsız değişkenleri açık bir türse açık bir türdür.
Kapalı tür, açık bir tür olmayan bir türdür.
Çalışma zamanında, genel tür bildirimi içindeki kodun tümü, genel bildirime tür bağımsız değişkenleri uygulanarak oluşturulan kapalı oluşturulmuş bir tür bağlamında yürütülür. Genel türdeki her tür parametresi belirli bir çalışma zamanı türüne bağlıdır. Tüm deyim ve ifadelerin çalışma zamanı işlemesi her zaman kapalı türlerle gerçekleşir ve açık türler yalnızca derleme zamanı işleme sırasında gerçekleşir.
Aynı ilişkisiz genel türden oluşturulurlarsa ve karşılık gelen tür bağımsız değişkenlerinin her biri arasında bir kimlik dönüştürmesi varsa, iki kapalı yapı türü kimlik dönüştürülebilir (§10.2.2) olur. Karşılık gelen tür bağımsız değişkenleri, kimliği dönüştürülebilir olan, kendilerinden ayrılmış türler veya tanımlama kümeleri olabilir. Kimliği dönüştürülebilir olan kapalı yapılı türler tek bir statik değişken kümesini paylaşır. Aksi takdirde, kapatılan her tür kendi statik değişken kümesine sahiptir. Çalışma zamanında açık bir tür olmadığından, açık bir türle ilişkili statik değişken yoktur.
8.4.4 İlişkili ve ilişkisiz türler
İlişkisiz tür terimi genel olmayan bir türe veya ilişkisiz genel türe başvurur. İlişkili tür terimi genel olmayan bir türe veya bir yapı türüne başvurur.
İlişkisiz bir tür, tür bildirimi tarafından bildirilen varlığa başvurur. İlişkisiz genel tür kendisi bir tür değildir ve değişken türü, bağımsız değişken veya dönüş değeri olarak ya da temel tür olarak kullanılamaz. İlişkisiz genel türe başvurulabilecek tek yapı ifadedir typeof
(§12.8.18).
8.4.5 Kısıtlamaları karşılama
Her yapılandırılmış türe veya genel yönteme başvurulsa, sağlanan tür bağımsız değişkenleri genel tür veya yöntemde (§15.2.5) bildirilen tür parametresi kısıtlamalarına karşı denetlenmektedir. Her where
yan tümce için, adlandırılmış tür parametresine karşılık gelen tür bağımsız değişkeni A
aşağıdaki gibi her kısıtlamaya karşı denetlenmektedir:
- Kısıtlama bir
class
tür, arabirim türü veya tür parametresiyse, kısıtlamada görünen herhangi bir tür parametresinin yerine sağlanan tür bağımsız değişkenleriyle bu kısıtlamayı temsil etmesine izin verinC
. Kısıtlamayı karşılamak için, türünA
aşağıdakilerden birine göre türeC
dönüştürülebilir olması gerekir: - Kısıtlama başvuru türü kısıtlaması ()
class
ise, türA
aşağıdakilerden birini karşılamalı:-
A
bir arabirim türü, sınıf türü, temsilci türü, dizi türü veya dinamik türdür.
Not:
System.ValueType
veSystem.Enum
bu kısıtlamayı karşılayan başvuru türleridir. son not-
A
, başvuru türü (§8.2) olarak bilinen bir tür parametresidir.
-
- Kısıtlama değer türü kısıtlaması ()
struct
ise, türA
aşağıdakilerden birini karşılamalı:-
A
birstruct
tür veyaenum
türdür, ancak null atanabilir bir değer türü değildir.
Not:
System.ValueType
veSystem.Enum
bu kısıtlamayı karşılamayan başvuru türleridir. son not-
A
değer türü kısıtlamasını (§15.2.5) içeren bir tür parametresidir.
-
- Kısıtlama oluşturucu kısıtlaması
new()
ise, türüA
olmamalıdırabstract
ve genel parametresiz bir oluşturucuya sahip olmalıdır. Aşağıdakilerden biri doğruysa bu durum geçerlidir:-
A
bir değer türüdür, çünkü tüm değer türlerinin bir ortak varsayılan oluşturucu (§8.3.3) vardır. -
A
, oluşturucu kısıtlamasını (§15.2.5) içeren bir tür parametresidir. -
A
değer türü kısıtlamasını (§15.2.5) içeren bir tür parametresidir. -
A
class
soyut olmayan ve parametresiz açıkça bildirilen bir ortak oluşturucu içerir. -
A
değildirabstract
ve varsayılan bir oluşturucuya sahiptir (§15.11.5).
-
Bir tür parametresinin kısıtlamalarından biri veya daha fazlası verilen tür bağımsız değişkenleri tarafından karşılanmazsa derleme zamanı hatası oluşur.
Tür parametreleri devralınmadığından, kısıtlamalar da hiçbir zaman devralınmaz.
Örnek: Aşağıda,
D
türü parametresindeT
T
kısıtlamayı belirterek temelclass
B<T>
tarafından uygulanan kısıtlamayı karşılaması gerekir. Buna karşılık,class
E
herhangi bir için uygulandığındanList<T>
kısıtlamaIEnumerable
belirtmeye gerek yokturT
.class B<T> where T: IEnumerable {...} class D<T> : B<T> where T: IEnumerable {...} class E<T> : B<List<T>> {...}
son örnek
8.5 Tür parametreleri
Tür parametresi, parametrenin çalışma zamanında bağlı olduğu bir değer türünü veya başvuru türünü belirten bir tanımlayıcıdır.
type_parameter
: identifier
;
Bir tür parametresinin örneği birçok farklı tür bağımsız değişkeniyle oluşturulabildiğinden, tür parametreleri diğer türlerden biraz farklı işlemlere ve kısıtlamalara sahiptir.
Not: Bunlar şunlardır:
- Tür parametresi, bir temel sınıfı (§15.2.4.2) veya arabirimi (§18.2.4) bildirmek için doğrudan kullanılamaz.
- Tür parametrelerinde üye arama kuralları, tür parametresine uygulanan kısıtlamalara (varsa) bağlıdır. Bunlar §12.5'te ayrıntılı olarak yer alır.
- Tür parametresi için kullanılabilir dönüştürmeler, tür parametresine uygulanan kısıtlamalara (varsa) bağlıdır. Bunlar §10.2.12 ve §10.3.8 ile ayrıntılı olarak anlatılır.
- Tür
null
parametresinin başvuru türü (§10.2.12) olarak bilinmesi dışında değişmez değer, tür parametresi tarafından verilen türe dönüştürülemez. Ancak, bunun yerine varsayılan ifade (§12.8.21) kullanılabilir. Ayrıca, tür parametresi tarafından verilen türe sahip bir değer, değer türü kısıtlaması olmadığı sürece ve (==
) kullanılarak!=
null ile karşılaştırılabilir.- İfade
new
(§12.8.17.2), yalnızca tür parametresi bir constructor_constraint veya değer türü kısıtlaması (§15.2.5) ile kısıtlanmışsa tür parametresiyle kullanılabilir.- Tür parametresi öznitelik içinde herhangi bir yerde kullanılamaz.
- Tür parametresi, statik bir üyeyi veya iç içe türü tanımlamak için üye erişiminde (§12.8.7) veya tür adında (§7.8) kullanılamaz.
- Tür parametresi unmanaged_type (§8.8) olarak kullanılamaz.
son not
Tür olarak, tür parametreleri yalnızca bir derleme zamanı yapısıdır. Çalışma zamanında, her tür parametresi, genel tür bildirimine bir tür bağımsız değişkeni sağlayarak belirtilen bir çalışma zamanı türüne bağlıdır. Bu nedenle, tür parametresiyle bildirilen bir değişkenin türü, çalışma zamanında , §8.4.3 kapalı bir tür olarak oluşturulacaktır. Tür parametreleriyle ilgili tüm deyimlerin ve ifadelerin çalışma zamanı yürütmesi, bu parametre için tür bağımsız değişkeni olarak sağlanan türü kullanır.
8.6 İfade ağacı türleri
İfade ağaçları , lambda ifadelerinin yürütülebilir kod yerine veri yapıları olarak temsil edilmesine izin verir. İfade ağaçları, herhangi bir temsilci türü olan formun ifade ağacı türlerinin değerleridir.System.Linq.Expressions.Expression<TDelegate>
TDelegate
Bu belirtimin geri kalanı için bu türlere kısaltması Expression<TDelegate>
kullanılarak başvurulacaktır.
Lambda ifadesinden temsilci türüne D
dönüştürme varsa, ifade ağacı türüne Expression<TDelegate>
dönüştürme de vardır. Lambda ifadesinin temsilci türüne dönüştürülmesi lambda ifadesi için yürütülebilir koda başvuran bir temsilci oluştururken, ifade ağacı türüne dönüştürme, lambda ifadesinin ifade ağacı gösterimini oluşturur. Bu dönüştürmenin diğer ayrıntıları §10.7.3'te sağlanmıştır.
Örnek: Aşağıdaki program bir lambda ifadesini hem yürütülebilir kod hem de ifade ağacı olarak temsil eder. dönüştürmesi
Func<int,int>
olduğundan, için bir dönüştürme de vardırExpression<Func<int,int>>
:Func<int,int> del = x => x + 1; // Code Expression<Func<int,int>> exp = x => x + 1; // Data
Bu atamaların ardından temsilci
del
, döndürenx + 1
bir yönteme başvurur ve ifade ağacı exp ifadesi ifadesini açıklayan bir veri yapısınax => x + 1
başvurur.son örnek
Expression<TDelegate>
türünde Compile
bir temsilci oluşturan bir örnek yöntemi TDelegate
sağlar:
Func<int,int> del2 = exp.Compile();
Bu temsilciyi çağırmak, ifade ağacı tarafından temsil edilen kodun yürütülmesine neden olur. Bu nedenle, yukarıdaki del
tanımları dikkate alır ve del2
eşdeğerdir ve aşağıdaki iki deyim aynı etkiye sahip olur:
int i1 = del(1);
int i2 = del2(1);
Bu kodu i1
yürüttkten sonra ve i2
her ikisi de değerine 2
sahip olur.
tarafından Expression<TDelegate>
sağlanan API yüzeyi, yukarıda açıklanan bir Compile
yöntem gereksiniminin ötesinde uygulama tanımlıdır.
Not: İfade ağaçları için sağlanan API'nin ayrıntıları uygulama tanımlı olsa da, bir uygulamanın şunları gerçekleştirmesi beklenir:
- Bir lambda ifadesinden dönüştürmenin sonucu olarak oluşturulan bir ifade ağacının yapısını incelemek ve yanıtlamak için kodu etkinleştirme
- kullanıcı kodu içinde programlı olarak oluşturulacak ifade ağaçlarını etkinleştirme
son not
8.7 Dinamik tür
Türüdynamic
, diğer tüm türler tarafından kullanılan statik bağlamanın aksine , §12.3.2'de ayrıntılı olarak açıklandığı gibi dinamik bağlama kullanır.
Türü dynamic
, aşağıdakiler dışında ile özdeş object
olarak kabul edilir:
- Tür
dynamic
ifadelerindeki işlemler dinamik olarak bağlanabilir (§12.3.3). - Her ikisi de adaysa tür çıkarımı (§12.6.3) tercih
dynamic
object
edilir. -
dynamic
olarak kullanılamaz- object_creation_expression türü (§12.8.17.2)
- class_base (§15.2.4)
- member_access predefined_type (§12.8.7.1)
- işlecin işleneni
typeof
- öznitelik bağımsız değişkeni
- kısıtlama
- uzantı yöntemi türü
- struct_interfaces (§16.2.5) veya interface_type_list (§15.2.4.1) içindeki tür bağımsız değişkeninin herhangi bir bölümü.
Bu denklik nedeniyle, aşağıdakiler şunları tutar:
- Örtük kimlik dönüştürmesi var
- ve arasında
object
dynamic
- ile değiştirirken
dynamic
aynı olan, yapılı türler arasındaobject
- ile değiştirirken
dynamic
aynı olan tanımlama grubu türleri arasındaobject
- ve arasında
- ve 'den
object
örtük ve açık dönüştürmeler de ve içindynamic
geçerlidir. - ile
dynamic
değiştirilirkenobject
aynı olan imzalar aynı imza olarak kabul edilir. - Türü
dynamic
, çalışma zamanında türündenobject
ayırt edilemez. - Türündeki
dynamic
bir ifade dinamik ifade olarak adlandırılır.
8.8 Yönetilmeyen türler
unmanaged_type
: value_type
| pointer_type // unsafe code support
;
unmanaged_type, ne bir reference_type ne de yönetilmeyen olma zorunluluğu olmayan bir type_parameter olan ve türü unmanaged_typeolmayan örnek alanları içermeyen herhangi bir türdür. Başka bir deyişle, unmanaged_type aşağıdakilerden biridir:
-
sbyte
, ,byte
, ,short
,ushort
,int
, ,uint
,long
,ulong
,char
,float
double
veyadecimal
.bool
- Herhangi bir enum_type.
- Kullanıcı tanımlı struct_type, yalnızca unmanaged_typeörnek alanlarını içerir.
- Yönetilmeyen olarak kısıtlanmış herhangi bir tür parametresi.
- Herhangi bir pointer_type (§23.3).
8.9 Başvuru Türleri ve null atanabilirlik
8.9.1 Genel
Null atanabilir başvuru türü, null atanamayan başvuru türüne bir nullable_type_annotation (?
) eklenerek belirtilir. Boş değer atanamayan başvuru türü ile karşılık gelen null atanabilir türü arasında anlamsal bir fark yoktur; her ikisi de bir nesneye veya null
başvurusu olabilir. nullable_type_annotation varlığı veya yokluğu, bir ifadenin null değerlere izin verip vermediğini bildirir. Bir ifade bu amaca göre kullanılmadığında derleyici tanılama sağlayabilir. İfadenin null durumu §8.9.5 içinde tanımlanır. Null atanabilir başvuru türü ve karşılık gelen null atanamaz başvuru türü (§10.2.2) arasında bir kimlik dönüştürmesi vardır.
Başvuru türleri için iki null atanabilirlik biçimi vardır:
-
nullable: null atanabilir-reference-type atanabilir
null
. Varsayılan null durumu belki-null'tır. -
null atanamaz: Null atanamayan başvuruya değer
null
atanmamalıdır. Varsayılan null durumu null değil.
Not: ve
R
türleriR?
, aynı temel türR
olan ile temsil edilir. Bu temel türün değişkeni bir nesneye başvuru içerebilir veya değerinull
olabilir ve bu değer "başvuru yok" ifadesini gösterir. son not
Null atanabilir başvuru türü ile karşılık gelen null atanamayan başvuru türü arasındaki bozulma ayrımı, derleyicinin tanılama oluşturmasını sağlar. Derleyici , §8.2.1'de tanımlandığı gibi nullable_type_annotation izin vermelidir. Tanılamalar uyarılarla sınırlı olmalıdır. Ne boş değer atanabilir ek açıklamaların varlığı veya yokluğu ne de boş değer atanabilir bağlamın durumu, derleme zamanında oluşturulan tanılama iletilerindeki değişiklikler dışında bir programın derleme süresini veya çalışma zamanı davranışını değiştiremez.
8.9.2 Null değer atanamayan başvuru türleri
Null değer atanamayan başvuru türü, formun T
başvuru türüdür; burada T
türün adıdır. Null değer atanamayan bir değişkenin varsayılan null durumu null değildir. Null olmayan bir değerin gerekli olduğu durumlarda belki null olan bir ifade kullanıldığında uyarılar oluşturulabilir.
8.9.3 Boş değer atanabilir başvuru türleri
Formun T?
başvuru türü (örneğinstring?
), null atanabilir bir başvuru türüdür. Null atanabilir bir değişkenin varsayılan null durumu null olabilir. Ek açıklama ?
, bu türdeki değişkenlerin null atanabilir olduğunu gösterir. Derleyici, uyarı vermek için bu amaçları tanıyabilir. Boş değer atanabilir ek açıklama bağlamı devre dışı bırakıldığında, bu ek açıklamayı kullanmak bir uyarı oluşturabilir.
8.9.4 Null atanabilir bağlam
8.9.4.1 Genel
Her kaynak kodu satırının boş değer atanabilir bir bağlamı vardır. Boş değer atanabilir bağlam denetimi (§8.9.4.3) ve null atanabilir uyarılar (§8.9.4.4) için ek açıklamalar ve uyarılar bayrakları sırasıyla. Her bayrak etkinleştirilebilir veya devre dışı bırakılabilir. Derleyici, herhangi bir başvuru değişkeninin null durumunu belirlemek için statik akış analizini kullanabilir. Başvuru değişkeninin null durumu (§8.9.5) null değil, belki null veya belki de varsayılan.
Null atanabilir bağlam, null atanabilir yönergeler (§6.5.9) ve/veya kaynak kodun dışındaki uygulamaya özgü bir mekanizma aracılığıyla kaynak kodu içinde belirtilebilir. Her iki yaklaşım da kullanılırsa, null atanabilir yönergeler bir dış mekanizma aracılığıyla yapılan ayarların yerini alır.
Null atanabilir bağlamın varsayılan durumu uygulama tanımlıdır.
Bu belirtim boyunca, boş değer atanabilir yönerge içermeyen veya geçerli null atanabilir bağlam durumuyla ilgili hiçbir deyimi yapılmayan tüm C# kodunun, hem ek açıklamaların hem de uyarıların etkinleştirildiği null atanabilir bir bağlam kullanılarak derlendiği varsayılır.
Not: Her iki bayrağın da devre dışı bırakıldığı null atanabilir bağlam, başvuru türleri için önceki standart davranışla eşleşir. son not
8.9.4.2 Null atanabilir devre dışı bırakma
Hem uyarı hem de ek açıklama bayrakları devre dışı bırakıldığında, null atanabilir bağlam devre dışı bırakılır.
Null atanabilir bağlam devre dışı bırakıldığında:
- Ek açıklamasız başvuru türünün bir değişkeni ile başlatıldığında veya değeri
null
atandığında uyarı oluşturulmaz. - Başvuru türündeki bir değişken null değere sahip olduğunda uyarı oluşturulmaz.
- herhangi bir başvuru türü
T
için içindeki ek açıklama?
T?
bir ileti oluşturur ve türüT?
ileT
aynıdır. - Herhangi bir tür parametresi kısıtlaması
where T : C?
için içindeki ek açıklama?
C?
bir ileti oluşturur ve türüC?
ileC
aynıdır. - Herhangi bir tür parametresi kısıtlaması
where T : U?
için içindeki ek açıklama?
U?
bir ileti oluşturur ve türüU?
ileU
aynıdır. - Genel kısıtlama
class?
bir uyarı iletisi oluşturur. tür parametresi bir başvuru türü olmalıdır.Not: Bu ileti, "uyarı" yerine "bilgilendirme" olarak nitelenir, bu nedenle bu iletinin ilgisiz olan null atanabilir uyarı ayarının durumuyla karıştırılmaması gerekir. son not
- Null-forgiving işlecinin
!
(§12.8.9) hiçbir etkisi yoktur.
Örnek:
#nullable disable annotations string? s1 = null; // Informational message; ? is ignored string s2 = null; // OK; null initialization of a reference s2 = null; // OK; null assignment to a reference char c1 = s2[1]; // OK; no warning on dereference of a possible null; // throws NullReferenceException c1 = s2![1]; // OK; ! is ignored
son örnek
8.9.4.3 Boş değer atanabilir ek açıklamalar
Uyarı bayrağı devre dışı bırakıldığında ve ek açıklama bayrağı etkinleştirildiğinde, null atanabilir bağlam ek açıklamalardır.
Null atanabilir bağlam ek açıklamalar olduğunda:
- herhangi bir başvuru türü
T
için, içindeki?
ek açıklamaT?
null atanabilir bir tür olduğunu belirtirkenT?
, açıklama ek açıklamasızT
null atanamaz. - Null atanabilirlikle ilgili tanılama uyarısı oluşturulmaz.
- Null-forgiving işleci
!
(§12.8.9), işleneninin analiz edilen null durumunu ve hangi derleme zamanı tanılama uyarılarının üretildiğini değiştirebilir.
Örnek:
#nullable disable warnings #nullable enable annotations string? s1 = null; // OK; ? makes s2 nullable string s2 = null; // OK; warnings are disabled s2 = null; // OK; warnings are disabled char c1 = s2[1]; // OK; warnings are disabled; throws NullReferenceException c1 = s2![1]; // No warnings
son örnek
8.9.4.4 Null atanabilir uyarılar
Uyarı bayrağı etkinleştirildiğinde ve ek açıklama bayrağı devre dışı bırakıldığında, null atanabilir bağlam uyarılardır.
Null atanabilir bağlam uyarılar olduğunda, derleyici aşağıdaki durumlarda tanılama oluşturabilir:
- Belki null olduğu belirlenen bir başvuru değişkeni başvurulmaz.
- Null olmayan türde bir başvuru değişkeni, null olabilecek bir ifadeye atanır.
-
?
null atanabilir başvuru türünü not etmek için kullanılır. - null-forgiving işleci
!
(§12.8.9), işleneninin null durumunu null değil olarak ayarlamak için kullanılır.
Örnek:
#nullable disable annotations #nullable enable warnings string? s1 = null; // OK; ? makes s2 nullable string s2 = null; // OK; null-state of s2 is "maybe null" s2 = null; // OK; null-state of s2 is "maybe null" char c1 = s2[1]; // Warning; dereference of a possible null; // throws NullReferenceException c1 = s2![1]; // The warning is suppressed
son örnek
8.9.4.5 Null atanabilir etkinleştirme
Hem uyarı bayrağı hem de ek açıklama bayrağı etkinleştirildiğinde, null atanabilir bağlam etkinleştirilir.
Null atanabilir bağlam etkinleştirildiğinde:
- herhangi bir başvuru türü
T
için, içindeki?
ek açıklamaT?
null atanabilir bir tür oluştururkenT?
, ek açıklamasızT
null atanamaz. - Derleyici, herhangi bir başvuru değişkeninin null durumunu belirlemek için statik akış analizini kullanabilir. Null atanabilir uyarılar etkinleştirildiğinde, başvuru değişkeninin null durumu (§8.9.5) null değil, null veya belki de varsayılan ve
- null-forgiving işleci
!
(§12.8.9), işleneninin null durumunu null değil olarak ayarlar. - Bir tür parametresinin null durumu, karşılık gelen tür bağımsız değişkeninin null durumu ile eşleşmiyorsa, derleyici uyarı verebilir.
8.9.5 Nullabiliteler ve null durumlar
Derleyicinin statik analiz gerçekleştirmesi veya null atanabilirlikle ilgili tanılama uyarıları oluşturması gerekmez.
Bu alt makalenin geri kalanı koşullu normatiftir.
Tanılama uyarıları oluşturan bir derleyici bu kurallara uygundur.
Her ifadenin üç null durumundanbiri vardır:
- belki null: İfadenin değeri null olarak değerlendirilebilir.
- belki de varsayılan: İfadenin değeri, bu tür için varsayılan değer olarak değerlendirilebilir.
- not null: İfadenin değeri null değil.
İfadenin varsayılan null durumu türüne ve bildirildiğinde ek açıklama bayrağının durumuna göre belirlenir:
- Null atanabilir başvuru türünün varsayılan null durumu:
- Bildirimi, ek açıklama bayrağının etkinleştirildiği metinde olduğunda null olabilir.
- Bildirimi, ek açıklama bayrağının devre dışı bırakıldığı metinde olduğunda null değil.
- Null değer atanamayan başvuru türünün varsayılan null durumu null değildir.
Not: Tür
default(T)
durum kısıtlanmamış tür parametreleriyle kullanılır. Null değer atanamayan tür için etki alanında null olmadığından, durum belki de varsayılandır. son not
Boş değer atanamayan bir başvuru türünün değişkeni (§9.2.1) başlatıldığında veya ek açıklama bayrağının etkinleştirildiği metinde bildirildiğinde null olabilecek bir ifadeye atandığında tanılama oluşturulabilir.
Örnek: Bir parametrenin null atanabilir olduğu ve bu değerin null atanamayan bir türe atandığı aşağıdaki yöntemi göz önünde bulundurun:
#nullable enable public class C { public void M(string? p) { // Warning: Assignment of maybe null value to non-nullable variable string s = p; } }
Derleyici, null olmayabilecek parametrenin null olmaması gereken bir değişkene atandığı bir uyarı verebilir. Parametre, atamadan önce null kontrolüne tabi tutulursa, derleyici bunu null yapılabilirlik durumu çözümlemesinde kullanabilir ve uyarıda bulunmayabilir.
#nullable enable public class C { public void M(string? p) { if (p != null) { string s = p; // No warning // Use s } } }
son örnek
Derleyici, çözümlemesinin bir parçası olarak değişkenin null durumunu güncelleştirebilir.
Örnek: Derleyici, programınızdaki deyimleri temel alarak durumu güncelleştirmeyi seçebilir:
#nullable enable public void M(string? p) { int length = p.Length; // Warning: p is maybe null string s = p; // No warning. p is not null if (s != null) { int l2 = s.Length; // No warning. s is not null } int l3 = s.Length; // Warning. s is maybe null }
Önceki örnekte, bir derleyici
int length = p.Length;
deyiminden sonra,p
null durumunun null olmadığını karar verebilir. Null olsaydı, bu deyim birNullReferenceException
oluştururdu. Bu, koddan önceif (p == null) throw NullReferenceException();
gelen davranışa benzer, ancak yazılan kod bir uyarı üretebilir ve bunun amacı örtük olarak bir özel durumun oluşturulabileceği konusunda uyarmaktır. son örnek
Yönteminin ilerleyen bölümlerinde kod, null başvuru olmadığını denetler s
. null-state değeri s
, null işaretli blok kapatıldıktan sonra null olarak değişebilir. Kodun null olabileceği varsayılarak yazılmış olduğu için, derleyici s
'ın null olabileceğini çıkarabilir. Genellikle, kod null denetimi içerdiğinde, derleyici değerin null olabileceğini çıkarsayabilir:
Örnek: Aşağıdaki ifadelerin her biri null denetimin bir biçimini içerir.
o
'ın boş durumu, her bir ifadenin ardından boş değil durumundan belki boş hale gelebilir.#nullable enable public void M(string s) { int length = s.Length; // No warning. s is not null _ = s == null; // Null check by testing equality. The null state of s is maybe null length = s.Length; // Warning, and changes the null state of s to not null _ = s?.Length; // The ?. is a null check and changes the null state of s to maybe null if (s.Length > 4) // Warning. Changes null state of s to not null { _ = s?[4]; // ?[] is a null check and changes the null state of s to maybe null _ = s.Length; // Warning. s is maybe null } }
Hem otomatik özellik hem de alan benzeri olay bildirimleri, derleyici tarafından oluşturulan bir yedekleme alanını kullanır. Null durum analizi, olay veya özelliğe yapılan atamanın derleyici tarafından oluşturulan bir yedekleme alanına yapılan atama olduğunu çıkarsayabilir.
Örnek: Bir derleyici, otomatik bir özellik veya alan benzeri bir etkinliği yazmanın karşılık gelen derleyici tarafından oluşturulan arka plan alanını yazdığını belirleyebilir. Özelliğin null durumu, yedekleme alanının durumuyla eşleşir.
class Test { public string P { get; set; } public Test() {} // Warning. "P" not set to a non-null value. static void Main() { var t = new Test(); int len = t.P.Length; // No warning. Null state is not null. } }
Önceki örnekte, oluşturucu
P
null olmayan bir değere ayarlamaz ve derleyici bir uyarı verebilir.P
özelliğine erişildiğinde uyarı yoktur, çünkü özelliğin türü null atanamaz bir başvuru türüdür. son örnek
Derleyici, bir özelliği (§15.7) durumlu bir değişken olarak veya bağımsız alma ve ayarlama erişimcileri olarak (§15.7.3) işleyebilir.
Örnek: Derleyici bir özelliğe yazmanın özelliği okumanın null durumunu mu değiştireceğini yoksa bir özelliğin okunmasının bu özelliğin null durumunu mu değiştireceğini seçebilir.
class Test { private string? _field; public string? DisappearingProperty { get { string tmp = _field; _field = null; return tmp; } set { _field = value; } } static void Main() { var t = new Test(); if (t.DisappearingProperty != null) { int len = t.DisappearingProperty.Length; // No warning. A compiler can assume property is stateful } } }
Önceki örnekte, için yedekleme alanı
DisappearingProperty
okunduğunda null olarak ayarlanmıştır. Ancak, derleyici bir özelliği okumanın bu ifadenin null durumunu değiştirmediğini varsayabilir. son örnek
Derleyici, null durumunu null değil olarak ayarlamak için değişken, özellik veya olayı dereferans eden herhangi bir ifade kullanabilir. Null olsaydı, başvuru kaldırma ifadesi bir NullReferenceException
oluştururdu:
Örnek:
public class C { private C? child; public void M() { _ = child.child.child; // Warning. Dereference possible null value var greatGrandChild = child.child.child; // No warning. } }
son örnek
Koşullu normatif metnin sonu
ECMA C# draft specification