Makale Özeti

C# 2.0 ile birlikte duyurulan Generic yapilari, Vb.Net e de eklendi, bu makalede Vb.Net te Generic yapilarinin nasil kullanildigini inceleyecegiz.

Makale

Visual Basic .Net 8 da Genericler

Uzun zaman önce C# 2.0 ile birlikte generic lerin geleceğini öğrenmiştik. Ancak Vb.Net te bu yönde bir gelişme yoktu. Sessizce Vb.Net 8.0 a da Generic ler eklenmiş durumda, Genericlerin amacı türden bağımsız işler yapabilme.

Generic lerin mantığını şöyle düşünelim, bir classımız var ve belli bir işlem yapıyor, ancak bu classımızın işlemi, metinsel (string) türde olabilir, rakamsal türlerde yada biraz daha geniş bakarsak, .Net teki herhangi bir class yada kendi yazdığımız bir class tipi de olabilir. Bu tarz bir class ın içindeki örneğin, sırala metodunu nasıl tanımlamak gerekir ? rakam tanımlarsak, metinsel türlerle iş yapamayız. Metin tanımlarsak, diğer class larda iş yapamayız, o zaman en mantıklısı object yani en büyük veri tipini tanımlamak ve istediğimiz veri tipine daha sonra dönüştürmek (Cast etmek) ama sonucuda bilemiyoruz ? o zaman geri dönüş tipinide object tanımlamalıyız...

Farkındamısınız ? biraz maliyetli bir iş değilmi ? sürekli object ten ihtiyacımız olan bir tipe cast etmek, sonra ondan bir başka tipe... programınızın ne kadar yavaş çalışacağını düşündünüzmü ?

İşte .Net teki generic ler bunun için varlar. Tipten bağımsız işlemler yapabilmek için, sizin diyeceğiniz sadece X tipini al ve buna göre işlemler yap demek, ve tipi class ı kullanırken kendizin belirlemesi... böylece class hangi tip ile çalışacağını bilecek ve casting gibi maliyetli işlerle uğraşmayacaksınız, gelen ve işlem sonucunda dönen tip belirli olacak... ne güzel değilmi ? :)

Bunun için Vb.Net te yeni bir keyword eklenmiş durumda... “of” keyword ü, bu keyword ile bu class ın hangi tipten olması gerektiğini belirliyorsunuz, ve classın instancesini alırken class a bu tipi belirliyorsunuz, buda size daha performanslı programlar çıkartmanızı sağlıyor.

Peki nasıl kullanılıyor bu generic ler onu inceleyelim. Mesela, yine Visual Basic in yeni sürümü ile gelen My yapılarını kullanarak generic kullanımına bir örnek yapalım (Kadir Sümerkent arkadaşımın yazdığı ve konuyu gerçekten çok başarılı aktardığı makaleye buradan erişebilirsiniz...) 

Amacım sistemdeki o sırada bulunan driverlerın bir listesini alıp, örneğin bu driverlardaki boş yerin ne kadar olduğunu bulmak olsun, aşşağıdaki kod bu işi yapıyor (amacım bu işi yapmak değil Generic leri anlatmak o yüzden kodda ne yaptığıma çok değinmeyeceğim)

        Dim DriverBilgileri As System.Collections.ObjectModel.ReadOnlyCollection(Of System.IO.DriveInfo) = My.Computer.FileSystem.Drives

        For Each DriverBilgisi As IO.DriveInfo In DriverBilgileri

            If (DriverBilgisi.DriveType <> IO.DriveType.CDRom) Then

                MessageBox.Show(DriverBilgisi.AvailableFreeSpace.ToString())

            End If

        Next

Dikkat edin ilk tanımladığım değişkenin tipi nedir ? System.Collections.ObjectModel.ReadOnlyCollection tipinde, ne demek bu, .Net FW 2.0 ın içinde bir metot var, bir collection oluşturmuşlar, amacı sadece okunması, yani bu collection a eklemek diye bir durum yok, ancak bu class ı oluştururken bir tip belirtmeleri gerekiyordu, bu tipide eğer generic ler olmasaydı muhtemelen object tipinde belirteceklerdi. Ancak bu yapıda tip belirlemeyi  kullanıcının seçmesini istemişler, böylece o tipe göre çalışacak ve buna göre işlemlerini çok daha hızlı yapabilecek.

Yukarıdaki resime dikkat ederseniz örneğin tanımladığım DriverBilgileri değişkeninin Item property sinde benden bir değer istiyor ve geriye System.IO.DriveInfo döndürüyor. Bende buna göre hiç casting yapmadan değeri direk atayabiliyorum.

Peki kendi Generic Classımızı nasıl yazacağız ? çok kolay, sadece classı tanımlarken tipini belirteceğiz, böylece classımızı kullananlar, instace alırken bu tipi verecek ve classımızın davranışı buna göre şekillenecek, aşağıda çok basit olarak bir Generic Class tanımlaması bulacaksınız.

Public Class BenimGenericim(Of T)

    '...

End Class

Genelde Genericler T harfi ile gösterilir (Type in T sinden geliyor) bizde bu şekilde tanımladık.

Örneğin şöyle bir kod yazabilirsiniz...

Public Class BenimGenericim(Of T)

    Dim deger As T

    Public Property DegerAta() As T

        Get

            Return deger

        End Get

        Set(ByVal value As T)

            deger = value

        End Set

    End Property

End Class

Bu class T tipinden bir değer bekliyor, bu verilen T tipinden bir ismi deger olan değişken oluşturuluyor ve daha sonra bu değişkene değer atanması için yine T tipinden bir property yazılıyor. Örneğimizi biraz daha geliştirelim. Aşağıdaki kodda yazılmış bir class var bu class bir array tutuyor ve bu arraye ekle metodu ile değer ekleyebiliyorsunuz, getir metodu ilede eklenilen en son değeri geri döndürüyor. Bu class ı istediğiniz gibi gelişyirebilirsiniz. Amacım sadece size şeklini göstermek.

Public Class benimArrayim(Of T)

    Dim arrayim(10) As T

    Dim boyut As Integer

    Public Sub New()

        boyut = 0

    End Sub

    Public Sub Ekle(ByVal eleman As T)

        If boyut > arrayim.Length Then

            ReDim Preserve arrayim(boyut * 2)

        End If

        arrayim(boyut) = eleman

        boyut += 1

    End Sub

    Public Function Getir() As T

        Return arrayim(boyut - 1)

    End Function

End Class

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim k As benimArrayim(Of String) = New benimArrayim(Of String)

        k.Ekle("cenk")

        k.Ekle("elif")

        MessageBox.Show(k.Getir)

    End Sub

Yukarıda ne yaptığımızı açıklayalım, benimArrayim diye bir class tanımlıyorum ve T yi tipim olarak belirliyorum... sonra classın içinde arrayim diye bir array tanımlıyorum boyutunu 10 olarak veriyorum tipine dikkat edin, tipinide T tipinden diyorum.

Daha sonra iki metot yazıyorum ilki Ekle metodu, T tipinden bir değişken alıyor, arrayin boyutunu 10 ayarlamıştım, ama kullanıcı 11. yi eklemek isteyebili bundan dolayı eğer kullanıcı 10 elemandan fazla eklemek isterse, boyutunu arttırıyorum. Ama önemli olan tarafı arrayime sırasıyla o elemanlanı tek tek ekliyorum. Getir metodum ise en son eklenen elemanı geriye döndürüyor, geri dönüş tipine dikkat T tipinde.

Bu makalemizde bu kadar, Aykut Taşdelen arkadaşımın yazdığı C# 2.0 versiyonunuda buradan okuyabilirsiniz.

Sorularınız, öneri ve eleştirileriniz için

cenk.caglar@yazgelistir.com