Aracılığıyla paylaş


C# türü sistemi

C# kesin olarak yazılan bir dildir. Her değişkenin ve sabitin bir türü vardır, aynı değer olarak değerlendirilen her ifade gibi. C# öncelikli olarak normatif bir tür sistemi kullanır. Normatif tür sistemi, her türü tanımlamak için adları kullanır. C# dilinde, struct, classve interface türleri de dahil olmak üzere record türlerin tümü adlarıyla tanımlanır. Her yöntem bildirimi, her parametre için ve dönüş değeri için bir ad, tür ve türü (değer, referans veya çıkış) belirtir. .NET sınıf kitaplığı, çok çeşitli yapıları temsil eden yerleşik sayısal türleri ve karmaşık türleri tanımlar. Bu yapılar dosya sistemini, ağ bağlantılarını, nesne koleksiyonlarını ve dizilerini ve tarihleri içerir. Tipik bir C# programı, sınıf kitaplığındaki türleri ve programın sorun etki alanına özgü kavramları modelleyen kullanıcı tanımlı türleri kullanır.

C# ayrıca tuple ve anonim türler gibi yapısal türleri de destekler. Yapısal türler , her üyenin adları ve türleri ve bir ifadedeki üyelerin sırası ile tanımlanır. Yapısal türlerin benzersiz adları yoktur.

Bir tür içinde depolanan bilgiler aşağıdaki öğeleri içerebilir:

  • Türündeki bir değişkenin gerektirdiği depolama alanı.
  • Gösterebileceği en büyük ve en düşük değerler.
  • içerdiği üyeler (yöntemler, alanlar, olaylar vb.).
  • Devraldığı temel tür.
  • Uyguladığı arabirimler.
  • İzin verilen işlemler.

Derleyici, kodunuzda gerçekleştirilen tüm işlemlerin tür güvenli olduğundan emin olmak için tür bilgilerini kullanır. Örneğin, türünde intbir değişken bildirirseniz, derleyici ek ve çıkarma işlemlerine ek olarak değişkenini kullanmanıza olanak tanır. Türündeki bir değişkende boolaynı işlemleri gerçekleştirmeye çalışırsanız, derleyici aşağıdaki örnekte gösterildiği gibi bir hata oluşturur:

int a = 5;
int b = a + 2; //OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

Uyarı

C ve C++ geliştiricileri, C# dilinde bool'ün int'e dönüştürülemez olduğuna dikkat edin.

Derleyici, tür bilgilerini yürütülebilir dosyaya meta veri olarak ekler. Ortak dil çalışma zamanı (CLR), belleği ayırıp geri kazandığında tür güvenliğini daha da garanti etmek için çalışma zamanında bu meta verileri kullanır.

Değişken bildirimlerinde türleri belirtme

Bir programda değişken veya sabit bildirdiğinizde, türünü belirtmeniz veya derleyicinin var türü çıkarması için anahtar sözcüğünü kullanmanız gerekir. Aşağıdaki örnekte hem yerleşik sayısal türleri hem de karmaşık kullanıcı tanımlı türleri kullanan bazı değişken bildirimleri gösterilmektedir:

// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):
char firstLetter = 'C';
var limit = 3;
int[] source = [0, 1, 2, 3, 4, 5];
var query = from item in source
            where item <= limit
            select item;

Yöntem parametresi türlerini ve dönüş değerlerini yöntem bildiriminde belirtirsiniz. Aşağıdaki imza, giriş bağımsız değişkeni olarak bir int gerektiren ve bir dize döndüren bir yöntemi gösterir:

public string GetName(int ID)
{
    if (ID < names.Length)
        return names[ID];
    else
        return String.Empty;
}
private string[] names = ["Spencer", "Sally", "Doug"];

Bir değişkeni bildirdikten sonra yeni bir türle yeniden oluşturamazsınız ve bildirilen türüyle uyumsuz bir değer atayamazsınız. Örneğin, bir int bildirip ardından ona bir true Boole değeri atayamazsınız. Ancak, değerleri yeni değişkenlere atadığınız veya yöntem bağımsız değişkenleri olarak geçirdiğiniz durumlar gibi diğer türlere dönüştürebilirsiniz. Derleyici otomatik olarak veri kaybına neden olmayan bir tür dönüştürmesi gerçekleştirir. Veri kaybına neden olabilecek bir dönüştürme için kaynak kodda bir atama gerekir.

Daha fazla bilgi için bkz. Dönüştürme ve Tür Dönüştürmeleri.

Yerleşik türler

C# standart bir yerleşik tür kümesi sağlar. Bu türler tamsayıları, kayan nokta değerlerini, Boole ifadelerini, metin karakterlerini, ondalık değerleri ve diğer veri türlerini temsil eder. Dil ayrıca yerleşik string ve object türleri de içerir. Bu türleri herhangi bir C# programında kullanabilirsiniz. Yerleşik türlerin tam listesi için bkz. Yerleşik türler.

Özel türler

İlgili veri üyelerini depolamak için tanımlama kümeleri kullanarak yapısal türler oluşturun. Bu türler birden çok üyeyi barındıran bir yapı sağlar. Tuple'lar sınırlı özelliklere sahiptir. Bunlar değerler için bir kapsayıcıdır. Oluşturabileceğiniz en basit türler bunlardır. Daha sonra davranışa ihtiyacınız olduğunu düşünebilirsiniz. Bu durumda, bir tuple'ı struct veya class öğesine dönüştürebilirsiniz.

structKendi özel türlerinizi oluşturmak için , class, interface, enum, ve record yapılarını kullanın. .NET sınıf kitaplığının kendisi, kendi uygulamalarınızda kullanabileceğiniz özel türlerden oluşan bir koleksiyondur. Varsayılan olarak, sınıf kitaplığında en sık kullanılan türler herhangi bir C# programında kullanılabilir. Diğer türleri, bunları sağlayan pakete açıkça bir paket bağlantısı ekleyerek erişilebilir hale getirirsiniz. Derleyici pakete bir başvuruya sahip olduktan sonra, bu paketin derlemelerinde bildirilen türlerin değişkenlerini ve sabitlerini kaynak kodunda bildirebilirsiniz.

Tür tanımlarken ilk kararlarınızdan biri, türünüz için hangi yapıyı kullanacağınıza karar vermektir. Aşağıdaki liste bu ilk kararın vermesine yardımcı olur. Bazı seçenekler çakışıyor. Çoğu senaryoda, birden fazla seçenek makul bir seçimdir.

  • Veri türü uygulama etki alanınızın bir parçası değilse ve davranış içermiyorsa yapısal bir tür kullanın.
  • Veri depolama boyutu küçükse, en fazla 64 bayt, struct veya record struct seçin.
  • Tür değişmezse veya tahribatsız mutasyon istiyorsanız, bir struct veya record struct seçin.
  • Türünüzün eşitlik için değer semantiği olması gerekiyorsa, record class veya record struct birini seçin.
  • Tür öncelikli olarak verileri depolamak içinse ve minimum davranışa sahipse, record class veya record struct öğesini seçin.
  • Tür bir devralma hiyerarşisinin parçasıysa, record class veya class öğesini seçin.
  • Tür çok biçimlilik kullanıyorsa bir class seçin.
  • Birincil amaç davranışsa bir classseçin.

Ayrıca, interfacebir sözleşmeyi modellemeyi de seçebilirsiniz: ilişkisiz türler tarafından uygulanabilen üyeler tarafından açıklanan davranış. Arabirimler soyut olup, bu arabirimden devralan tüm class veya struct türler tarafından uygulanması gereken üyeleri bildirir.

Ortak tür sistemi

Ortak tür sistemi devralma ilkesini destekler. Türler, temel türler olarak adlandırılan diğer türlerden türetilebilir. Türetilen tür, yöntemleri, özellikleri ve temel türün diğer üyelerini devralır (bazı kısıtlamalarla). Temel tür de başka bir türden türetilebilir; bu durumda türetilen tür devralma hiyerarşisindeki her iki temel türün üyelerini de devralır.

(C# anahtar sözcüğü: ), gibi System.Int32 yerleşik sayısal türler de dahil olmak üzere tüm türler tek bir temel türden int türetilir( C# anahtar sözcüğü: System.Object). object Bu birleşik tür hiyerarşisi Ortak Tür Sistemi (CTS) olarak adlandırılır. C# dilinde devralma hakkında daha fazla bilgi için bkz . Devralma.

CTS'deki her tür bir değer türü veya başvuru türü olarak tanımlanır. Bu türler .NET sınıf kitaplığındaki tüm özel türleri ve kendi kullanıcı tanımlı türlerinizi içerir:

  • struct veya record struct anahtar sözcüklerini kullanarak tanımladığınız türler değer türleridir. Tüm yerleşik sayısal türler şeklindedir structs.
  • , classveya record class anahtar sözcüklerini kullanarak recordtanımladığınız türler başvuru türleridir.

Başvuru türleri ve değer türleri farklı derleme zamanı kurallarına ve farklı çalışma zamanı davranışlarına sahiptir.

Uyarı

En yaygın kullanılan türlerin tümü ad alanında System düzenlenir. Ancak, bir türün bulunduğu ad alanının değer türü veya başvuru türü olmasıyla hiçbir ilişkisi yoktur.

Sınıflar ve yapılar, .NET'teki ortak tür sisteminin temel yapılarından ikisidir. Her yapı temelde bir mantıksal birim olarak birbirine ait olan bir veri ve davranış kümesini kapsülleyen bir veri yapısıdır. Veriler ve davranışlar sınıfın, yapının veya kaydın üyeleridir . Üyeler, bu makalenin devamında listelendiği gibi yöntemlerini, özelliklerini, olaylarını vb. içerir.

Sınıf, yapı veya kayıt bildirimi, çalışma zamanında örnek veya nesne oluşturmak için kullandığınız şemaya benzer. adlı PersonPerson bir sınıf, yapı veya kayıt tanımlarsanız, türün adıdır. Bir ptüründe değişken Person bildirir ve başlatırsanız, p'nin bir Personnesnesi veya örneği olduğu söylenir. Aynı Person türde birden çok örnek oluşturabilirsiniz ve her örneğin özelliklerinde ve alanlarında farklı değerler olabilir.

Sınıf bir başvuru türüdür. Türünde bir nesne oluşturduğunuzda, nesneyi atadığınız değişken yalnızca bu belleğe bir başvuru içerir. Nesne başvuruyu yeni bir değişkene atadığınızda, yeni değişken özgün nesneye başvurur. Her ikisi de aynı verilere başvuracağından, bir değişken aracılığıyla yaptığınız değişiklikler diğer değişkene yansıtılır.

Yapı bir değer türüdür. Bir yapı oluşturduğunuzda, yapıyı atadığınız değişken yapının gerçek verilerini tutar. Yapıyı yeni bir değişkene atadığınızda kopyalanır. Bu nedenle yeni değişken ve özgün değişken aynı verilerin iki ayrı kopyasını içerir. Bir kopyada yaptığınız değişiklikler diğer kopyayı etkilemez.

Kayıt türleri başvuru türleri (record class) veya değer türleri (record struct) olabilir. Kayıt türleri, değer eşitliğini destekleyen yöntemler içerir.

Genel olarak, daha karmaşık davranışları modellemek için sınıfları kullanın. Sınıflar genellikle bir sınıf nesnesi oluşturulduktan sonra değiştirdiğiniz verileri depolar. Yapılar, küçük veri yapıları için en uygun olanıdır. Yapılar genellikle yapı oluşturulduktan sonra değiştirmediğiniz verileri depolar. Kayıt türleri, fazladan derleyici sentezlenmiş üyeleri olan veri yapılarıdır. Kayıtlar genellikle nesne oluşturulduktan sonra değiştirmediğiniz verileri depolar.

Değer türleri

Değer türleri System.ValueType'den türetilir, bu da System.Object'den türetilmiştir. System.ValueType türetiminden gelen türler CLR'de özel bir davranışa sahiptir. Değer türü değişkenleri doğrudan değerlerini içerir. Bir yapının belleği, değişkenin bildirıldığı bağlamda satır içinde ayrılır. Değer türleri olan record struct türlerini bildirebilir ve kayıtlar için sentezlenmiş üyeleri ekleyebilirsiniz.

İki değer türü kategorisi vardır: struct ve enum.

Yerleşik sayısal türler yapılardır ve bunlara erişebileceğiniz alanlar ve yöntemler vardır:

// constant field on type byte.
byte b = byte.MaxValue;

Ancak, değerleri basit, birleşik olmayan türlermiş gibi deklaratif olarak tanımlar ve atarsınız.

byte num = 0xA;
int i = 5;
char c = 'Z';

Değer türleri sabittir. gibi System.Int32herhangi bir değer türünden tür türetemezsiniz. Bir yapıyı, yalnızca System.ValueType'dan devralabileceği için, kullanıcı tanımlı herhangi bir sınıf veya yapıdan devralacak şekilde tanımlayamazsınız. Ancak, bir yapı bir veya daha fazla arabirim uygulayabilir. Bir yapı türünü, uyguladığı herhangi bir arabirim türüne dönüştürebilirsiniz. Bu atama, bir kutulama işleminin yapıyı yönetilen yığındaki bir başvuru türü nesnesi içinde sarmalamasına neden olur. Kutulama işlemleri, System.Object veya herhangi bir arabirim türünü giriş parametresi olarak alan bir yönteme değer türü geçirdiğinizde gerçekleşir. Daha fazla bilgi için bkz. Kutulama ve Kutu Açma.

Kendi özel değer türlerinizi oluşturmak için struct anahtar sözcüğünü kullanın. Yapı genellikle aşağıdaki örnekte gösterildiği gibi küçük bir ilişkili değişken kümesi için kapsayıcı olarak kullanılır:

public struct Coords(int x, int y)
{
    public int X { get; init; } = x;
    public int Y { get; init; } = y;
}

Yapılar hakkında daha fazla bilgi için bkz . Yapı türleri. Değer türleri hakkında daha fazla bilgi için bkz. Değer türleri.

Değer türlerinin diğer kategorisi enum. Numaralandırma, adlandırılmış tamsayı sabitleri kümesini tanımlar. Örneğin, .NET sınıf kitaplığındaki System.IO.FileMode numaralandırması, bir dosyanın nasıl açılması gerektiğini belirten adlandırılmış sabit tamsayılar kümesi içerir. Aşağıdaki örnekte gösterildiği gibi tanımlanmıştır:

public enum FileMode
{
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,
}

System.IO.FileMode.Create sabiti 2 değerine sahiptir. Ancak, kaynak kodu okuyan insanlar için ad çok daha anlamlıdır ve bu nedenle sabit sabit sayılar yerine numaralandırmaları kullanmak daha iyidir. Daha fazla bilgi için bkz. System.IO.FileMode.

Tüm sabit listeler System.Enum sınıfından, System.Enum ise sınıfından devralınır. Yapılara uygulanan tüm kurallar enumlar için de geçerlidir. Sabit listeleri hakkında daha fazla bilgi için bkz. Numaralandırma türleri.

Referans türleri

class, record class, record, delegate, dizi veya interface olarak tanımladığınız bir tür reference type'dir.

Bir reference type türünde bir değişken bildirdiğinizde, ona bu türden bir örnek atayana ya da new işleciyle bir örnek oluşturana kadar değeri null içerir. Aşağıdaki örnek, bir sınıfın oluşturulmasını ve atanma işlemini gösterir:

MyClass myClass = new();
MyClass myClass2 = myClass;

işlecini interface kullanarak doğrudan bir new örneği oluşturamazsınız. Bunun yerine, arabirimini uygulayan bir sınıfın örneğini oluşturun ve atayın. Aşağıdaki örneği göz önünde bulundurun:

MyClass myClass = new();

// Declare and assign using an existing value.
IMyInterface myInterface = myClass;

// Or create and assign a value in a single statement.
IMyInterface myInterface2 = new MyClass();

Nesneyi oluşturduğunuzda, sistem yönetilen yığında bellek ayırır. değişkeni yalnızca nesnenin konumuna bir başvuru içerir. Yönetilen yığındaki türler hem ayrılırken hem de geri alındığında ek işlem yükü gerektirir. Atık toplama , geri kazanma işlemini gerçekleştiren CLR'nin otomatik bellek yönetimi işlevidir. Ancak, atık toplama da yüksek oranda iyileştirilmiştir ve çoğu senaryoda bir performans sorunu oluşturmaz. Çöp toplama hakkında daha fazla bilgi için bkz. Otomatik Bellek Yönetimi.

Tüm diziler, öğeleri değer türleri olsa bile başvuru türleridir. Diziler örtük olarak sınıfından System.Array türetilir. Bunları, aşağıdaki örnekte gösterildiği gibi C# tarafından sunulan basitleştirilmiş söz dizimini kullanarak bildirir ve kullanırsınız:

// Declare and initialize an array of integers.
int[] nums = [1, 2, 3, 4, 5];

// Access an instance property of System.Array.
int len = nums.Length;

Referans türleri devralmayı tamamen destekler. Bir sınıf oluşturduğunuzda, korumalı olarak tanımlanmayan başka bir arabirimden veya sınıftan devralabilirsiniz. Diğer sınıflar sınıfınızdan devralabilir ve sanal yöntemlerinizi geçersiz kılabilir. Kendi sınıflarınızı oluşturma hakkında daha fazla bilgi için bkz . Sınıflar, yapılar ve kayıtlar. Devralma ve sanal yöntemler hakkında daha fazla bilgi için bkz . Devralma.

Literal değer türleri

C# dilinde, derleyici sabit değerlere bir tür atar. Sayının sonuna bir harf ekleyerek sayısal değişmez değerin nasıl yazılacağını belirtebilirsiniz. Örneğin, değerin 4.56 olarak floatele alınması gerektiğini belirtmek için, sayıdan sonra bir "f" veya "F" ekleyin: 4.56f. Bir harf eklemezseniz, derleyici literalin türünü tahmin eder. Harf sonekleri ile belirtebileceğiniz türler hakkında daha fazla bilgi için bkz. Tam sayı türleri ve Kayan noktalı sayısal türler.

Literal değerlerin belirli tipleri olduğu için ve tüm türler en nihayetinde System.Object sınıfından türetildiği için, aşağıdaki kod gibi bir kod yazabilir ve derleyebilirsiniz:

string s = "The answer is " + 5.ToString();
// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();
// Outputs: "System.Int32"
Console.WriteLine(type);

Genel türler

Bir veya daha fazla tür parametresi içeren ve gerçek tür (somut tür) için yer tutucu işlevi gören bir tür bildirin. Türün bir örneğini oluşturduğunda, istemci kodu somut türü belirtir. Bu türlere genel türler adı verilir. Örneğin, .NET türü System.Collections.Generic.List<T> , kurala göre adlı Tbir tür parametresine sahiptir. Türün bir örneğini oluşturduğunuzda, listenin içerdiği nesnelerin türünü belirtirsiniz, örneğin string:

List<string> stringList = new List<string>();
stringList.Add("String example");
// compile time error adding a type other than a string:
stringList.Add(4);

type parametresini kullanmak, her öğeyi nesneye dönüştürmek zorunda kalmadan herhangi bir öğe türünü tutmak için aynı sınıfı yeniden kullanmayı mümkün kılar. Derleyici koleksiyonun öğelerinin belirli türünü bildiği ve örneğin önceki örnekte nesneye bir tamsayı eklemeye çalıştığınızda derleme zamanında hata oluşturabileceğinden, genel koleksiyon sınıfları stringList. Daha fazla bilgi için bkz. Genel Bilgiler.

Tanımlama kümeleri ve anonim türler

Genel API'leri kullanarak bu değerleri depolamak veya geçirmek istemiyorsanız, basit ilişkili değer kümeleri için bir tür oluşturmak zor olabilir. Bu amaçla tanımlama kümeleri veya anonim türler oluşturabilirsiniz. Daha fazla bilgi için bkz. tuples ve Anonim Türler.

Boş değer atanabilen değer türleri

Normal değer türlerinin değeri nullolamaz. Ancak, türünden sonra bir ekleyerek ? oluşturabilirsiniz. Örneğin, int? değerine intde sahip olabilecek bir null türdür. Null atanabilir değer türleri, genel yapı türünün System.Nullable<T>örnekleridir. Boş değer atanabilir değer türleri özellikle sayısal değerlerin olabileceği nullveritabanlarına ve veritabanlarından veri geçirirken yararlıdır. Daha fazla bilgi için bakınız Nullable değer türleri.

Örtük tür bildirimleri

var anahtar sözcüğünü kullanarak bir yerel değişkeni örtük olarak tanımlayın (ancak sınıf üyelerini değil). Değişken, derleme zamanında bir tür almaya devam eder, ancak derleyici türü sağlar. Daha fazla bilgi için Örtük Olarak Yazılan Yerel Değişkenler bölümüne bakın.

Derleme zamanı türü ve çalışma zamanı türü

Değişken, farklı derleme zamanı ve çalışma zamanı türlerine sahip olabilir. Derleme zamanı türü, kaynak koddaki değişkenin bildirilen veya çıkarım yapılan türüdür. Çalışma zamanı türü, bu değişken tarafından başvuruda bulunılan örneğin türüdür. Bu iki tür genellikle aşağıdaki örnekte olduğu gibi aynıdır:

string message = "This is a string of characters";

Diğer durumlarda, derleme zamanı türü aşağıdaki iki örnekte gösterildiği gibi farklıdır:

object anotherMessage = "This is another string of characters";
IEnumerable<char> someCharacters = "abcdefghijklmnopqrstuvwxyz";

Önceki örneklerin her ikisinde de, çalışma zamanı türü bir string'dir. Derleme zamanı türü ilk satırda object ve ikinci satırda IEnumerable<char>.

Bir değişken için iki tür farklıysa, derleme zamanı türü ve çalışma zamanı türünün ne zaman geçerli olduğunu anlamak önemlidir. Derleme zamanı türü, derleyicinin gerçekleştirilir tüm eylemleri belirler. Bu derleyici eylemleri yöntem çağrısı çözümlemesini, aşırı yükleme çözümlemesini ve kullanılabilir örtük ve açık atamaları içerir. Çalışma zamanı türü, çalışma zamanında çözümlenen tüm eylemleri belirler. Bu çalışma zamanı eylemleri, sanal yöntem çağrılarının gönderilmesini, is ve switch ifadelerinin değerlendirilmesini ve diğer tür testi API'lerini içerir. Kodunuzun türlerle nasıl etkileşime geçtiğini daha iyi anlamak için hangi eylemin hangi tür için geçerli olduğunu belirleyin.

Daha fazla bilgi için aşağıdaki makalelere bakın:

C# dil belirtimi

Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# söz dizimi ve kullanımı için kesin kaynaktır.