• Sonuç bulunamadı

Şablon Türler (Generics)

N/A
N/A
Protected

Academic year: 2022

Share "Şablon Türler (Generics)"

Copied!
57
0
0

Yükleniyor.... (view fulltext now)

Tam metin

(1)

Şablon Türler

(Generics)

(2)

CLR 1.0’da çalışma zamanında belli olmayan sınıfları kullanan esnek sınıf ve metotlar, Object sınıfı temel alınarak oluşturulması gerekmekteydi.

CLR 2.0’dan itibaren Generic’lerin kullanımı ile artık böyle bir zorunluluk mevcut değildir.

Generic sınıflar olabileceği gibi, generic

temsilci, interface ve metotlar da olabilir.

(3)

Avantaj / Dezavantaj

• Performans (Performance)

• Tip Günvenliği (Type Safety)

• Tekrar kod kullanımı (Binary code reuse)

• Kod Fazlalığı (Code Bloat)

• İsimlendirme (Naming Guidelines)

(4)

i)Performans

Generic’lerin en büyük avantajlarından birisi performanstır.

Herhangi bir değer tipinden üyeleri olan bir

koleksiyon üzerinde işlem yapılırken sık sık

boxing/unboxing işlemleri yapılır. Bu ise

performansta büyük ölçüde düşüşe neden olur.

(5)

Örnek

class Program {

static void Main(string[] args) {

ArrayList list = new ArrayList();

list.Add(44); //boxing

int i1 = (int)list[0]; // unboxing foreach (int i2 in list)

{

Console.WriteLine(i2); //unboxing }

} }

(6)

class Program {

static void Main(string[] args) {

List<int> list = new List<int>();

list.Add(44); //no boxing - Değer tipleri List<int> içinde saklanmakta int i1 = (int)list[0]; // unboxing, cast işlemine gerek yok.

foreach (int i2 in list) {

Console.WriteLine(i2); //unboxing }

} }

(7)

ii)Tip Güvenliği (Type Safety)

class Program

{ static void Main(string[] args) {

ArrayList list = new ArrayList();

list.Add(44);

list.Add("mystring");

list.Add(new Program());

int i1 = (int)list[0];

foreach (int i2 in list)

{ Console.WriteLine(i2);

} } }

?

(8)

class Program {

static void Main(string[] args) {

List<int> list = new List<int>();

list.Add(44);

list.Add("mystring");

list.Add(new Program());

int i1 = (int)list[0];

foreach (int i2 in list) {

Console.WriteLine(i2);

} } }

?

(9)

iii) Tekrar Kod Kullanımı (Binary Code Reuse)

• Generic ikili kodun tekrar kullanımına izin verirler. Generic sınıf bir defa tanımlanır ve başka tiplerde pekçok örneği (instance) oluşturulur.

• C++’dan farklı olarak kaynak koda erişmek

gerekli değildir.

(10)

Örneğin List<T> sınıfının (System.Collections.Generic) çeşitli örnekleri aşağıdadır:

• List<int> list = new List<int>();

list.Add(44);

• List<string> stringlist = new List<string>();

stringlist.Add(“bilgisayar mühendisliği”);

• List<MyClass> myclasslist = new List<MyClass>();

myclasslist.Add(new MyClass());

(11)

iV) Kod Fazlalığı (Code Bloat)

Generic sınıf tanımlaması assembly seviyesinde olduğundan, istenilen türde generic sınıf instance’ı oluşturmak, IL kodunda bu sınıfların aynılarının üretilmesini sağlamayacaktır.

Fakat, generic sınıflar JIT tarafından

derlendiğinde, istenilen her bir tür için yeni bir

sınıf oluşturulacaktır.

(12)

v) İsimlendirme (Naming Guidelines)

Generic türler program içerisinde kullanılacağında generic olmayan türlerden ayırt edilebilmesi gerekmektedir. Bunun için:

• Generic tip isimleri T harfi ile başlamalıdır.

• Generic türle ilgili eğer özel bir gereksinim

veya iki veya daha fazla generic tür

kullanılıyorsa tip isimleri için tanımlayıcı

isimler seçilmelidir.

(13)

• Public class List<T> { }

Public class LinkedList<T> { }

• Public class SortedList <TKey, TValue> { }

(14)

Generic Sınıfları Oluşturmak

(LinkedList Example-Şablon Tipleri Kullanmadan)

public class LinkListNode {

private object value;

public LinkListNode(object value) {

this.value = value;

}

public object Value {

get { return value;}

set { this.value = Value; } }

public LinkListNode Next { get; set; }

(15)

public class LinkListe {

public LinkListNode Head { get; private set; } public LinkListNode Tail { get; private set; } public LinkListNode temp {get; private set;}

public void AddFirst(LinkListNode value) {

temp = Head;

Head = value;

Head.Next = temp;

}

public void ekranayaz() { temp = Head;

while ((temp) != null) {

Console.WriteLine("{0}", temp.Value);

temp = temp.Next;

} } }

(16)

public class LinkListNode<T>

{

private T value;

public LinkListNode(T value) { this.value = value;

}

public T Value {

get { return value;}

set { this.value = Value; } }

public LinkListNode<T> Next { get; set; }

Generic Sınıfları Oluşturmak

(LinkedList Example-Şablon Tipleri Kullanarak)

(17)

public class LinkListe<T>

{ public LinkListNode<T> Head { get; private set; } public LinkListNode<T> Tail { get; private set; } public LinkListNode<T> temp {get; private set;}

public void AddFirst(LinkListNode<T> value) {

temp = Head;

Head = value;

Head.Next = temp;

}

public void ekranayaz() {

temp = Head;

while ((temp) != null)

{ Console.WriteLine("{0}", temp.Value);

temp = temp.Next;

} } }

(18)

class Singly_Link {

static void Main(string[] args) {

LinkListe<string> liste = new LinkListe<string> ();

LinkListNode<string> a1 = new LinkListNode<string>("Merhaba");

LinkListNode<string> a2 = new LinkListNode<string>("Bilgisayar");

LinkListNode<string> a3 = new LinkListNode<string>("Mühendisliği");

liste.AddFirst(a1);

liste.AddFirst(a2);

liste.AddFirst(a3);

Console.WriteLine("*************");

liste.ekranayaz();

} }

(19)

İkinci örnekte, LinkListe sınıfı, LinkListe<T>

yazımı ile şablon türe dönüştürülmüştür. Artık

LinkListe<T> , LinkListNode<T> türünden

elemanlar alabilir.

(20)

Şablon Tülerin Özellikleri

(Generic Classes’ Features)

(21)

Örnek

public class DocumentManager<T>

{

private readonly Queue<T> documentQueue = new Queue<T>();

public void AddDocument(T doc) {

lock (this) {

documentQueue.Enqueue(doc);

} }

public bool IsDocumentAvailable {

get { return documentQueue.Count > 0; } }

}

(22)

Lock Anahtar Sözcüğü

Lock anahtar sözcüğü bir threadin diğer başka bir threadin işlem yaptığı kritik bölgeye girmesini engellemektedir.

Lock anahatar sözcüğü ile kilitlenmiş olan nesneneye diğer threadin erişebilmesi için bu nesnenin release edilmesi gerekmektedir.

• http://msdn.microsoft.com/en-

us/library/c5kehkcz.aspx

(23)

Varsayılan Değerler (Default Values)

Şablon bir türe “null” değerini atamak mümkün değildir. Böyle bir durumda “default”

anahtar sözcüğü kullanılır.

Şimdi DocumentManager<T> sınıfımıza

GetDocument() metotdunu ekleyelim.

(24)

public T GetDocument() {

T doc = default(T);

lock (this) {

doc = documentQueue.Dequeue();

}

return doc;

}

(25)

Kısıtlar

(Constraints)

• DocumentManager<T> sınıfına

DisplayAll Documents() metotdunu ekleyelim.

(26)

public void DisplayAllDocuments() {

foreach (T doc in documentQueue) {

Console.WriteLine(doc.Title);

}

} ?

(27)

• Çalışma zamanında meydana gelen hatanın düzeltilebilmesi için şablon türde olan DocumentManager<T> sınıfında bazı kısıtlamalara gitmek gerekir.

• Kısıtlamaları sağlamak için “where” anahtar

sözcüğü kullanılır.

(28)

public class DocumentManager<T> where T:IDocument {

private readonly Queue<T> documentQueue = new Queue<T>();

public void AddDocument(T doc) {

lock (this) {

documentQueue.Enqueue(doc);

} }

public bool IsDocumentAvailable {

get { return documentQueue.Count > 0; } }

(29)

public T GetDocument() {

T doc = default(T);

lock (this) {

doc = documentQueue.Dequeue();

}

return doc;

}

public void DisplayAllDocuments() {

foreach (T doc in documentQueue) {

Console.WriteLine(doc.Title);

} } }

(30)

Değişik Kısıtlar da Mevcuttur

(31)

Inheritance

• Şablon bir tür, başka bir sınıftan veya şablon sınıftan türeyebilir.

• Bir arayüzü implement edebilir.

• Türeyen sınıf şablon türden olabilir veya

olmayabilir.

(32)

• public class LinkedList<T> : IEnumerable<T>

• public class Base<T>

{ …..

}

public class Derived<T>:Base<string>

(33)

public abstract class Calc<T>

{

public abstract T Add ( T x, T y);

public abstract T Sub(T x, T y);

}

public class SimpleCalc:Calc<int>

{

public override int Add (int x, int y) {

return x+y;

}

public override int Sub(int x, int y) {

return x - y;

} }

(34)

Statik Üyeler

Şablon türlerin statik üyeleri sınıfın bir örneği

tarafından paylaşılırlar.

(35)

public class StaticDemo<T>

{

public static int x;

}

static void Main(string[] args) {

StaticDemo<string>.x = 4;

StaticDemo<int>.x = 5;

Console.WriteLine(StaticDemo<string>.x);

}

?

(36)

Şablon Arayüzler (Generic Interfaces)

Sınıflarda olduğu gibi arayüzler ile birlikte de

şablon tipler kullanılabilmektedir.

(37)

public interface IComparable<T>

{

int CompareTo(T other);

}

public class Person : IComparable<Person>

{

public int CompareTo(Person other) {

return this.LastName.CompareTo(other.LastName);

}

. . . .

. . . .

}

(38)

Şablon Metotlar (Generic Methods)

Şablon türde sınıflar tanımlanabildiği gibi

şablon türde metotlar da tanımlanabilir.

(39)

class Program {

public static void Swap<T>(ref T x, ref T y) {

T temp;

temp = x;

x = y;

y = temp;

}

static void Main(string[] args) {

int i = 4;

int j = 5;

Swap<int>(ref i, ref j);

} }

(40)

Örnek

(41)

public class Account {

private string name;

public string Name { get { return name; } }

private decimal balance;

public decimal Balance { get { return balance; } }

public Account(string name, Decimal balance) {

this.name = name;

this.balance = balance;

} }

(42)

Bütün hesaplar (accounts) bir listede tutulsun.

class Program {

static void Main(string[] args) {

List<Account> accounts = new List<Account>();

accounts.Add(new Account("Christian", 1500));

accounts.Add(new Account("Sharon", 2200));

accounts.Add(new Account("Katie", 1800));

} }

(43)

Toplamı hesaplamak için tüm Account nesneleri üzerinde foreach döngüsü ile dolaşılabilir.

Foreach yapısı koleksiyon elemanları üzerinde

dolaşabilmek IEnumerable arayüzünü

kullandığı için toplamı hesaplamak için

yazılacak olan metot da, IEnumerable türünde

parametre almalıdır.

(44)

public static class Algorithm {

public static decimal AccumulateSimple(IEnumerable<Account> e) {

decimal sum = 0;

foreach (Account a in e) {

sum += a.Balance;

}

return sum;

} }

(45)

AccumulateSimple() metodu aşağıdaki şekilde çağırabilir.

public static class Algorithm {

static void Main(string[] args) {

List<Account> accounts = new List<Account>();

accounts.Add(new Account("Christian", 1500));

accounts.Add(new Account("Sharon", 2200));

accounts.Add(new Account("Katie", 1800));

decimal amount = Algorithm.AccumulateSimple(accounts);

} }

(46)

Aynı örnek için farklı bir Accumulate() metodu yazalım.

Şablon metotlarda şablon sınıflarda olduğu gibi “where” anahtar sözcüğü ile

sınırlandırmaya (constraint) gidilebilir.

(47)

public static class Algorithm {

public static decimal Accumulate<TAccount>(IEnumerable<TAccount>

coll) where TAccount : IAccount {

decimal sum = 0;

foreach (TAccount a in coll) {

sum += a.Balance;

}

return sum;

} }

(48)

class Program {

static void Main(string[] args) {

List<Account> accounts = new List<Account>();

accounts.Add(new Account("Christian", 1500));

accounts.Add(new Account("Sharon", 2200));

accounts.Add(new Account("Katie", 1800));

decimal amount = Algorithm.Accumulate<Account>(accounts);

Console.WriteLine(amount.ToString());

}

}

?

(49)

public class Account:IAccount {

private string name;

public string Name { get { return name; } }

private decimal balance;

public decimal Balance { get { return balance; } }

public Account(string name, Decimal balance) {

this.name = name;

this.balance = balance;

} }

(50)

Şablon türün parametresi derleyici tarafından , metodun parametresinden otomatik olarak

çıkarıldığından aşağıdaki gibi bir yazım da

geçerlidir.

(51)

class Program {

static void Main(string[] args) {

List<Account> accounts = new List<Account>();

accounts.Add(new Account("Christian", 1500));

accounts.Add(new Account("Sharon", 2200));

accounts.Add(new Account("Katie", 1800));

decimal amount = Algorithm.Accumulate(accounts);

Console.WriteLine(amount.ToString());

} }

(52)

Şablon Temsilciler

(Generic Delegates)

(53)

Account sınıfına ait örnekteki Accumulate()

isimli metodu aşağıdaki gibi değiştirelim.

(54)

public static class Algorithm {

public static TSummary Accumulate

<TInput, TSummary>

(IEnumerable<TInput> coll, Action<TInput,TSummary> action) {

TSummary sum = default(TSummary);

foreach (TInput input in coll) {

sum = action(input,sum);

}

return sum;

} }

Delegate Türünden

IEnumerable Türünden

(55)

Accumulate() metodunun ikinci parametresi Action temsilcisi türündendir. Action temsilcisini ise aşağıdaki şekilde tanımlamak mümküdür.

public delegate TSummary Action<TInput, Tsummary> (TInput t, TSummary u);

(56)

Accumulate() metodu aşağıdaki şekilde invoke

edilebilir.

(57)

class Program {

static void Main(string[] args) {

List<Account> accounts = new List<Account>();

accounts.Add(new Account("Christian", 1500));

accounts.Add(new Account("Sharon", 2200));

accounts.Add(new Account("Katie", 1800));

decimal amount = Algorithm.Accumulate<Account, decimal>(accounts, delegate(Account a, decimal d)

{return a.Balance + d;});

Console.WriteLine(amount.ToString());

} }

Referanslar

Benzer Belgeler

Bilgisayar dosya türünü şablon olarak seçtiğinizde dosya konumunu otomatik olarak varsayılan şablon dosyaları konumuna ayarlar.. (

Detay Bandı (Detail Bant).. Teklifte yer alması gereken alan için rapor kontrolleri bölümünde yer alan label alanı sürüklenir ve detail banda yerleştirilir. Örneğin; detail

Kredinin gecikme/temerrüde düşmesi halinde hesaplanacak gecikme faiz tutarı,mevcut taksit tutarına devlet faiz destek tutarı dahil edilerek toplam taksit tutarı

Yuvalanmış bir şablon oluşturmak için, önce orijinali veya temel şablonu kaydetmeli, sonra şablonu temel alan yeni bir belge oluşturmalı ve sonra bu belgeyi şablon

 İskelet protezlerde ana model üzerinde metal iskelete bağlı olarak hazırlanır... Mum duvarlar= Mum

Mesela, eşleştirme sorusu, çoktan seçmeli soru, açık uçlu soru gibi.. Farklı

Rotasyon şablon, lak, sodyumbikromat, mezur, beher, rotasyon şablon açma aparatı, kurutma dolabı, polimerizasyon dolabı, mikser, sanayi tipi buzdolabı, lak çekme makinesi, bant,

Hazırlanan şablonlar radyoloji işlemi yapılan hastanın onaylama işlemi yapıldıktan sonra sonuç rapor kısmında şablon tıklandıktan sonra aktarılacak şablon şablon