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 yöntem bildirimi, her giriş parametresi ve dönüş değeri için bir ad, tür ve tür (değer, başvuru veya çıkış) belirtir. .NET sınıf kitaplığı, yerleşik sayısal türleri ve çok çeşitli yapıları temsil eden karmaşık türleri tanımlar. Bunlar dosya sistemini, ağ bağlantılarını, koleksiyonları ve nesne 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ürdeki bir değişkenin gerektirdiği depolama alanı.
  • Gösterebileceği en büyük ve en düşük değerler.
  • İçeren üyeler (yöntemler, alanlar, olaylar vb.).
  • Devraldığı temel tür.
  • Uyguladığı arabirimler.
  • İzin verilen işlem türleri.

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şlemlerinde değişkeni kullanmanıza olanak tanır. Türündeki boolbir değişkende aynı 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;

Not

C ve C++ geliştiricileri, C# bool dilinde öğesinin olarak dönüştürülemediğini intfark eder.

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, derleyicinin var türü çıkarması için türünü belirtmeniz veya 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 gerektiren ve dize döndüren int 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 bildiremez ve sonra buna boole değeri trueatayamazsınız. Ancak, değerler başka türlere dönüştürülebilir, örneğin yeni değişkenlere atandığında veya yöntem bağımsız değişkenleri olarak geçirildiğinde. 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 kodunda atama yapılması gerekir.

Daha fazla bilgi için bkz . Tür Dönüştürmeleri 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 , classinterface, , enumve record yapılarını kullanırsınızstruct. .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 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ığı.

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 devralır. (C# anahtar sözcüğü: ) gibi System.Int32 yerleşik sayısal türler de dahil olmak üzere tüm türler nihai olarak tek bir temel türden System.Object türetilir (C# anahtar sözcüğü: object). int 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. veya record anahtar sözcüğünü class kullanarak tanı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.

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

Screenshot that shows CTS value types and reference types.

Not

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 bir 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. C# 9, bir tür sınıf olan kayıtları ekler. Her biri temelde bir mantıksal birim olarak bir araya gelen bir dizi veri ve davranışı 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. türünde bir değişken p bildirir ve başlatırsanız nesnesinin p veya örneğinin Personolduğu Personsöylenir. Aynı Person türde birden çok örnek 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.

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, 'den System.ValueTypetüretilen türünden System.Objecttüretilir. türetilen System.ValueType türlerin CLR'de özel davranışı vardır. Değer türü değişkenleri doğrudan değerlerini içerir. Bir yapı için bellek, değişkenin bildirıldığı bağlamda satır içinde ayrılır. Değer türü değişkenleri için ayrı yığın ayırma veya çöp toplama ek yükü yoktur. Değer türü olan türleri bildirebilir record struct ve kayıtlar için sentezlenmiş üyeleri dahil edebilirsiniz.

Değer türlerinin iki 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 toplama olmayan türlermiş gibi bildirir ve atarsınız:

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

Değer türleri korumalıdır. Bir türü, örneğin System.Int32herhangi bir değer türünden türetemezsiniz. Bir yapı yalnızca öğesinden devralabileceğinden, kullanıcı tanımlı herhangi bir sınıf veya yapıdan System.ValueTypedevralacak bir yapı 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çine sarmalamasına neden olur. Kutulama işlemleri, giriş parametresi olarak bir veya herhangi bir arabirim türünü alan bir System.Object yönteme bir 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 ilgili 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 kategorisidir enum. Sabit listesi, adlandırılmış integral sabitleri kümesini tanımlar. Örneğin, .NET sınıf kitaplığındaki numaralandırma, System.IO.FileMode 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,
}

Sabit System.IO.FileMode.Create 2 değerine sahiptir. Ancak ad, kaynak kodu okuyan insanlar için ç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 listeleri, 'den System.Enumdevralan öğesini devralır System.ValueType. Yapılara uygulanan tüm kurallar sabit listeleri için de geçerlidir. Sabit listeleri hakkında daha fazla bilgi için bkz. Numaralandırma türleri.

Başvuru türleri

, , record, delegatedizisi veya interface olarak classtanımlanan bir reference typetür.

bir değişkeni bildirildiğinde, siz bu türün reference typebir örneğini atayana veya işlecini kullanarak bir değişken oluşturana new kadar değeri null 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 işleci kullanılarak new doğrudan örneği oluşturulamaz. Bunun yerine, arabirimini uygulayan bir sınıfın örneğini oluşturun ve atayın. Aşağıdaki örneği inceleyin:

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 tutar. Yönetilen yığındaki türler hem atandığında hem de geri kazanıldığında ek yük gerektirir. Atık toplama , geri kazanmayı gerçekleştiren CLR'nin otomatik bellek yönetimi işlevselliğidir. Ancak çöp 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;

Başvuru türleri devralmayı tamamen destekler. Bir sınıf oluşturduğunuzda, korumalı olarak tanımlanmamış 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.

Değişmez değer türleri

C# dilinde değişmez 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 eklenmezse, derleyici değişmez değer için bir tür çıkaracaktır. Harf sonekleri ile hangi türlerin belirtilebileceği hakkında daha fazla bilgi için bkz . Tam sayı türleri ve Kayan nokta sayısal türleri.

Değişmez değerler yazıldığından ve tüm türler sonunda 'den System.Objecttüretildiğinden, 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 yer tutucu görevi görecek bir veya daha fazla türparametresiyle bildirilebilir. İstemci kodu, türün bir örneğini oluşturduğunda somut türü sağlar. Bu tür türlere genel türler adı verilir. Örneğin, .NET türü System.Collections.Generic.List<T> , kurala göre adı Tverilen bir tür parametresine sahiptir. Türün bir örneğini oluşturduğunuzda, listenin içereceğ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);

tür 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ın yeniden kullanılmasını mümkün kılar. Derleyici koleksiyonun öğelerinin belirli türünü bildiği ve örneğin önceki örnekte nesneye bir tamsayı stringList eklemeye çalıştığınızda derleme zamanında hata oluşturabildiğinden, genel koleksiyon sınıfları kesin olarak belirlenmiş koleksiyonlar olarak adlandırılır. Daha fazla bilgi için bkz. Genel Bilgiler.

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

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 hala derleme zamanında bir tür alır, ancak tür derleyici tarafından sağlanır. Daha fazla bilgi için bkz. Örtük Olarak Yazılan Yerel Değişkenler.

Yöntem sınırlarını depolamak veya geçirmek istemediğiniz basit ilgili değer kümeleri için adlandırılmış 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 null atanabilir değer türleri oluşturabilirsiniz. Örneğin, int? değerine nullde sahip olabilecek bir int 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 bkz. Null atanabilir 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 çıkarsanan türüdür. Çalışma zamanı türü, bu değişkenin başvurduğu ö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, IEnumerable<char> ikinci satırdadırobject.

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ı göndermeyi, değerlendirmeyi is ve ifadeleri ve switch 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 makaleleri inceleyin:

C# dili belirtimi

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