Menu

C# Sınıf ve Nesne: Alanlar, Metotlar, new ve Referanslar

C#'ta bir sınıf bildirmek, ona alanlar ve metotlar vermek, new ile nesne oluşturmak ve bir sınıfın referans tipi olmasının ne anlama geldiği: paylaşılan nesneler, null ve NullReferenceException, ToString ve nesne başlatıcılar.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Bir sınıf sizin tanımladığınız bir tiptir: verileri (alanlar) o veriler üzerinde çalışan kodla (metotlar) gruplar. Bir nesne ise bir sınıfın, çalışma zamanında new ile oluşturulan bir örneğidir. Tek sınıf, her biri kendi değerlerine sahip birçok nesne.

Bir sınıf bildirmek ve nesne oluşturmak

Bir sınıf bildirimi üyelerini süslü parantezlerin içinde listeler. Alanlar veriyi, metotlar davranışı tutar. new ClassName() bir nesne ayırır ve size ona bir referans verir.

Çıktı:

Maya: 120.50
Omar: 40
Withdraw 200 succeeded: False

Her nesnenin kendi Owner ve Balance'ı vardır. Bir metodun içinde Balance "bu metodun üzerinde çağrıldığı nesnenin bakiyesi" demektir; maya.Deposit ve omar.Deposit'in farklı sayıları değiştirmesinin nedeni budur. Bu örtük nesneye ad vermeniz gerektiğinde this olarak erişilebilir.

Atamadığınız alanlar varsayılan değerleriyle başlar: sayılar için 0, bool için false, string'ler ve diğer sınıf tipleri için null.

Buradaki üyeler Main'in onlara ulaşabilmesi için public'tir. Gerçek sınıflar genellikle alanları private tutar ve bunun yerine property'ler sunar; erişim belirleyiciler sayfasında kurallar vardır. Bir sınıf, nesne oluşturulduğunda alanlarını ayarlamak için bir constructor da bildirebilir; bu constructor'lar sayfasında ele alınır.

Bir sınıf bir referans tipidir

Sınıf tipindeki bir değişken nesneyi içermez. Heap'te yaşayan bir nesneye bir referans içerir. Değişkeni atamak referansı kopyalar, bu yüzden iki değişken aynı nesneyi gösterebilir.

Çıktı:

5
6
True
False

Burada üç sonuç ortaya çıkar:

  • Nesneyi second üzerinden değiştirmek first üzerinden görünür, çünkü yalnızca bir nesne vardır.
  • Bir nesneyi bir metoda geçirmek referansı geçirir. Metot nesnenin alanlarını değiştirebilir ve çağıran bunu görür. (Metodun içinde parametreye yeni bir nesne atamak çağıranın değişkenini etkilemez; bunun için ref gerekir.)
  • İki sınıf örneği üzerinde == varsayılan olarak referansları karşılaştırır: "bunlar aynı değerlere mi sahip?" değil "bu aynı nesne mi?". lookalike'ın verileri aynıdır ve yine de farklı bir nesnedir.

Atamada kopya ve değer karşılaştırması istiyorsanız değer tipi olan struct'lara ya da değere göre karşılaştıran record'lara bakın.

null ve NullReferenceException

Bir referans değişkeni "nesne yok" anlamına gelen null tutabilir. null üzerinden bir üye kullanmak, C# kodundaki en yaygın çalışma zamanı istisnası olan NullReferenceException'ı fırlatır.

Çıktı:

True
no city on file
NullReferenceException: Address was never set
Lisbon

Çözüm neredeyse hiçbir zaman istisnayı yakalamak değildir. Referansın neden null olduğunu bulun ve ya nesneyi daha erken oluşturun, ya kullanmadan önce kontrol edin ya da istisna fırlatmak yerine durup null veren null koşullu operatör ?.'yı kullanın. ?? ardından bir yedek sağlar. İki operatör de nullable tipler sayfasında ele alınır.

ToString'i override etmek

Her sınıf, ToString() sağlayan object'ten kalıtım alır. Kalıtılan sürüm tipin tam adını (varsa namespace'i dahil) döndürür; bu, yazdırmak istediğiniz şey nadiren olur. Onu override edin:

Çıktı:

Plain
Mug (8.50)
In cart: Mug (8.50)
Total line: Mug (8.50)

Console.WriteLine, string interpolation ve bir string ile + sizin için ToString() çağırır. Debugger da onu gösterir; bu yüzden nesneyi kendiniz hiç yazdırmasanız bile bir override işe yarar.

Nesne başlatıcılar

Bir nesne başlatıcı, public alanları ve property'leri nesne oluşturulduktan hemen sonra aynı ifadede ayarlar. Bir atama listesinden daha iyi okunur ve koleksiyon literal'lerinin içinde iyi çalışır.

Çıktı:

A12: 25 (0 extras)
A13: 40 (2 extras)

İkinci bilette iki ayrıntı var. Price = 40m alan başlatıcısının 25m'sini geçersiz kılar, çünkü nesne başlatıcı nesne oluşturulduktan sonra çalışır. Extras = { "Parking", "Poster" }'da new yoktur: alanın zaten tuttuğu listeyi değiştirmek yerine onun üzerinde Add çağırır.

Bir nesne başlatıcı bir constructor değildir. Yalnızca çağıran koddan erişilebilen üyeleri ayarlayabilir ve bir üyenin mutlaka ayarlanmasını zorunlu kılamaz. Bir nesne belirli değerler olmadan geçersizse onları bir constructor'da zorunlu kılın.

Partial sınıflar

partial anahtar kelimesi tek bir sınıfı birkaç dosyaya böler. Derleyici parçaları tek bir sınıfta birleştirir.

// Invoice.cs
public partial class Invoice
{
    public decimal Subtotal;
    public decimal Total() => Subtotal + Tax();
}

// Invoice.Tax.cs
public partial class Invoice
{
    private decimal Tax() => Subtotal * 0.2m;
}

Her parça partial demeli, aynı namespace'te ve aynı projede olmalıdır. Yaygın kullanım üretilen koddur: WinForms tasarımcıları, source generator'lar ve bazı ORM'ler bir parçayı yazar ve diğerini size bırakır, böylece yeniden üretmek kodunuzun üzerine asla yazmaz. Elle yazılmış bir sınıfı yalnızca kısaltmak için dosyalara bölmek genellikle iki sınıf olması gereken bir sınıfı gizler.

Yaygın hatalar

  • Bir nesneyi oluşturmadan önce kullanmak. Sınıf tipindeki bir alan, ona new ... atayana kadar null'dır. İlk üye erişimi NullReferenceException fırlatır.
  • Atamanın kopyalamasını beklemek. Bir sınıf için var b = a; aynı nesneye ikinci bir ad verir. Bağımsız bir nesneye ihtiyacınız olduğunda yeni bir nesne oluşturun ve değerleri kopyalayın.
  • Nesneleri == ile karşılaştırıp değer karşılaştırması beklemek. Sınıflar için, sınıf =='i aşırı yüklemedikçe (string'in yaptığı gibi) referansları karşılaştırır. İlgili alanları karşılaştırın ya da Equals'ı override edin.
  • Bir nesneyi yazdırıp tip adını almak. ToString()'i override edin.
  • Her şeyi public bildirmek. Küçük örneklerde çalışır, ama herhangi bir kodun nesneyi geçersiz bir duruma, örneğin negatif bir bakiyeye, sokmasına izin verir. Alanları private tutun ve kuralları kontrol eden metotlar üzerinden değiştirin.

Sıkça Sorulan Sorular

C#'ta sınıf nedir?

Sınıf, sizin tanımladığınız bir tiptir: veri (alanlar ve property'ler) ve davranıştan (metotlar) oluşan adlandırılmış bir grup. class Account { public decimal Balance; public void Deposit(decimal amount) { Balance += amount; } } bir tane bildirir. Sınıf bir plandır; ondan new ile nesneler oluşturana kadar hiçbir şey yapmaz.

C#'ta sınıf ile nesne arasındaki fark nedir?

Sınıf, kaynak kodda bir kez yazılan tanımdır. Nesne ise onun, çalışma zamanında new ile oluşturulan ve her örnek alanının kendi kopyasına sahip bir örneğidir. İki kez new Account() bakiyeleri birbirinden bağımsız, aynı sınıftan iki nesne verir.

C#'ta nesne nasıl oluşturulur?

new'in ardından sınıf adını ve constructor argümanlarını yazın: var account = new Account();. Public alanları ve property'leri aynı ifadede bir nesne başlatıcıyla ayarlayabilirsiniz: new Account { Owner = "Maya" }. Değişken nesnenin kendisini değil, yeni nesneye bir referansı tutar.

C#'ta neden NullReferenceException alıyorum?

null tutan bir değişken üzerinden bir üye (.Name, .Length, bir metot çağrısı) kullandınız, yani üzerinde işlem yapılacak bir nesne yok. Yaygın nedenler hiç atanmamış bir alan (sınıf alanları null olarak başlar), null döndüren bir arama ya da başarısızlıkta null döndüren bir metottur. if (x != null) ile kontrol edin, x?.Name kullanın ya da nesnenin kullanılmadan önce oluşturulduğundan emin olun.

C#'ta ToString nasıl override edilir?

Sınıfınızda public override string ToString() bildirin ve istediğiniz metni döndürün, örneğin public override string ToString() => $"{Name} ({Price:F2})";. O olmadan Console.WriteLine(obj) ve string interpolation sınıf adını yazdırır, çünkü object.ToString() bunu döndürür.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA