CodeBlanks Logo Icon CodeBlanks

Virtual dispatch

C# kursu · Orta seviye · Ders 63/116

Sanal metot tablosu ve çalışma zamanı dağıtımını öğrenirsin.

Sanal metot tablosu (vtable)

Bir sınıf virtual metot içeriyorsa derleyici arkada bir sanal metot tablosu (vtable) oluşturur. Her nesne bu tabloya gizli bir başvuru taşır. virtual çağrıda derleyici doğrudan değil, dolaylı çağrı üretir: tablodan gerçek metodu bulur.

Bu yüzden runtime dispatch denir. Sanal çağrı, doğrudan çağrıdan biraz yavaştır; ama modern donanımda fark genellikle önemsizdir. Performans kritikse sealed override yazarak son türevi kilitler ve tablo aramasını bazen kısaltabilirsin.

sealed override ile kilitleme

Bir override metodun daha fazla geçersiz kılınmasını engellemek için başına sealed eklersin: public sealed override void Speak(). Bu, derleyiciye “bu sınıftan türetilenler artık bu metodu değiştiremez” demektir.

Sealed override hem güvenlik (yanlışlıkla değiştirmeyi önler) hem de bazen performans (vtable aramasını bazen atlar) sağlar. Aşırı kullanma: gerçekten gerekmedikçe sınıfları mühürlemek genişletilebilirliği azaltır. Soyut bir hiyerarşinin uç noktalarında mantıklıdır.

Uygulama Sanal dispatch ile hayvan sesleri

Animal sınıfında public virtual void Speak() metodu Console.WriteLine("Ses") yazsın. Dog : Animal sınıfında override ile Console.WriteLine("Hav") yazsın. Cat : Animal sınıfında override ile Console.WriteLine("Miyav") yazsın. Main içinde List<Animal> oluştur; içine Dog, Cat, Animal koy. foreach ile Speak çağır.

Örnek çözümü göster
Animal { public override void Speak() { Console.WriteLine("Hav"); } } ve class Cat : Animal { public override void Speak() { Console.WriteLine("Miyav"); } } yaz. Main'de List<Animal> { new Dog(), new Cat(), new Animal() } oluştur ve foreach ile Speak çağır.
Örnek çözüm:
using System;
using System.Collections.Generic;

class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Ses");
    }
}

class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Hav");
    }
}

class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Miyav");
    }
}

class Program
{
    static void Main()
    {
        var animals = new List<Animal> { new Dog(), new Cat(), new Animal() };
        foreach (var a in animals)
        {
            a.Speak();
        }
    }
}

Kendini test et

  1. Anahtar kelimeyi etkisine eşle

    virtual
    vtable girişi oluşturur
    override
    vtable girişini değiştirir
    new
    Yeni yuva oluşturur
    sealed
    Daha fazla değişimi engeller
  2. Sanal dispatch ne zaman gerçekleşir?

    Animal a = new Dog();
    a.Speak();
    • Çalışma zamanında nesnenin türüne göre
    • Derleme zamanında referans türüne göre
    • Yalnızca sealed kullanılırsa
    • Yalnızca new kullanılırsa
    Cevabı göster

    Çalışma zamanında nesnenin türüne göre — Doğru. Sanal dispatch runtime'da nesnenin gerçek türüne göre yapılır.

  3. Geçersiz kılmayı kilitle

    public ____ override void Speak() { }
    Cevabı göster
    public sealed override void Speak() { }

Orta seviye bölümündeki tüm dersler