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. Her metot bildirimi, her giriş parametresi ve dönüş değeri için bir ad, veri türü ve türü (değer, başvuru 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. Bunlar 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.

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 ifadesinin int ifadesine 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 parametrelerinin ve dönüş değerlerinin türleri, yöntem bildiriminde belirtilir. 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 uyumlu olmayan bir değer atayamazsınız. Örneğin, bir int bildirip ardından ona bir true Boole değeri atayamazsınız. Ancak, değerler, örneğin yeni değişkenlere atandığında veya yöntem bağımsız değişkenleri olarak geçirildiğinde diğer türlere dönüştürülebilir. Veri kaybına neden olmayan bir tür dönüştürmesi derleyici tarafından otomatik olarak gerçekleştirilir. 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. Bunlar tamsayıları, kayan nokta değerlerini, Boole ifadelerini, metin karakterlerini, ondalık değerleri ve diğer veri türlerini temsil eder. Ayrıca yerleşik string ve object türleri de vardır. 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

Kendi özel türlerinizi oluşturmak için struct, class, interface, enumve record yapılarını kullanırsınız. .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ğerleri yalnızca bunları tanımlayan derlemeye açıkça bir proje başvurusu eklediğinizde kullanılabilir hale gelir. Derleyicinin derlemeye bir başvurusu olduktan sonra, kaynak kodunda bu derlemede bildirilen türlerin değişkenlerini (ve sabitlerini) bildirebilirsiniz. Daha fazla bilgi için bkz . .NET Sınıf Kitaplığı.

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. Seçeneklerde çakışma var. Çoğu senaryoda, birden fazla seçenek makul bir seçimdir.

  • 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çin kullanılıyorsa, record class veya record struct 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.

Ortak tür sistemi

.NET'te tür sistemi hakkında iki temel noktayı anlamak önemlidir:

  • 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. Yerleşik sayısal türler, örneğin System.Int32 (C# anahtar sözcüğü: int), dahil olmak üzere tüm türler, nihai olarak tek bir temel tür olan System.Object'den (C# anahtar sözcüğü: object) türetilir. 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. anahtar sözcüğünü struct kullanarak tanımladığınız türler değer türleridir; tüm yerleşik sayısal türler olur structs. Tanımladığınız türler, class veya record anahtar sözcüğünü kullanarak 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.

Aşağıdaki çizimde, CTS'deki değer türleri ve başvuru türleri arasındaki ilişki gösterilmektedir.

CTS değer türlerini ve başvuru türlerini gösteren ekran görüntüsü.

Uyarı

En yaygın kullanılan türlerin tümünün ad alanında System düzenlendiğini görebilirsiniz. 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 biri 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 kullanılan ş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ürünün birden çok örneği oluşturulabilir 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şturulduğunda, nesnenin atandığı değişken yalnızca bu belleğe bir başvuru içerir. Nesne başvurusu yeni bir değişkene atandığında, yeni değişken özgün nesneye başvurur. Her ikisi de aynı verilere başvuracağından, bir değişken aracılığıyla yapılan değişiklikler diğer değişkene yansıtılır.

Yapı bir değer türüdür. Bir yapı oluşturulduğunda, yapının atandığı değişken yapının gerçek verilerini tutar. Yapı yeni bir değişkene atandığında kopyalanır. Bu nedenle yeni değişken ve özgün değişken aynı verilerin iki ayrı kopyasını içerir. Bir kopyada yapılan 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, sınıflar daha karmaşık davranışları modellemek için kullanılır. Sınıflar genellikle bir sınıf nesnesi oluşturulduktan sonra değiştirilmesi amaçlanan 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ştirilmesi amaçlanmamış verileri depolar. Kayıt türleri, derleyici sentezlenmiş ek üyeleri olan veri yapılarıdır. Kayıtlar genellikle nesne oluşturulduktan sonra değiştirilmesi amaçlanmamış 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üründeki değişkenler için ayrı yığın ayırma veya çöp toplama ek yükü yoktur. 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. Herhangi bir değer türünden tür türetemezsiniz, örneğin System.Int32. 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ırsınız. 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
{
    public int x, y;

    public Coords(int p1, int p2)
    {
        x = p1;
        y = p2;
    }
}

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, delegate, dizi veya interface olarak tanımlanan bir reference type türüdür.

Belirli bir reference type türünde bir değişken bildirdiğinizde, bu türün bir örneğini atayana veya null işlemcisini kullanarak bir örnek oluşturana kadar new değerini içerir. Bir sınıfın oluşturulması ve atanma işlemi aşağıdaki örnekte gösterilmiştir:

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

interface, new işleci kullanılarak doğrudan örneklendirilemez. 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 MyClass();

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

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

Nesne oluşturulduğunda, bellek yönetilen yığında ayrılı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 sağlanan basitleştirilmiş söz dizimi ile 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 sabit değerler derleyiciden bir tür alır. 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. Hiçbir harf eklenmemişse, derleyici literaller için bir tür çıkarım yapar. Harf sonekleri ile hangi türlerin belirtilebileceği hakkında daha fazla bilgi için bkz. Tam sayı türleri ve Kayan noktalı sayısal türler.

Değişmez değerler türlendirilmiş olduğundan ve tüm türler sonunda System.Object'den türetilir, 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 tür, gerçek tür (somut tür) için bir veya daha fazla tür parametresinin yer tutucu görevi göreceği şekilde bildirilebilir. Türün bir örneğini oluşturduğunda, istemci kodu somut türü belirtir. Bu tür türlere genel türler adı verilir. Örneğin, .NET türü System.Collections.Generic.List<T>, kurala göre T adı verilen bir 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 parametresinin kullanılması, 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şturabildiğinden, genel koleksiyon sınıfları kesin stringList olarak adlandırılır. Daha fazla bilgi için bkz. Genel Bilgiler.

Örtük türler, anonim türler ve null değer atanabilen türler

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

Depolamayı veya yöntem sınırlarının dışına geçirmeyi amaçlamadığınız basit ilgili değer kümeleri için adlandırılmış bir tür oluşturmak uygun olmayabilir. Bu amaçla anonim türler oluşturabilirsiniz. Daha fazla bilgi için bkz. Anonim Türler.

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.

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ü, derleyici tarafından yapılan 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.