Unity 3D – Property’leri Tanıyalım (C#)

Yayınlandı: 16 Eylül 2015 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde

Uzun bir aradan sonra hepinize yeniden merhaba!

Bu kısa derste C#‘taki property‘lere değineceğim. Ben kendi kodlarımda zaman zaman property’lerden faydalanıyorum. Buna ilaveten, incelediğim bazı hazır kodlarda da bol bol property kullanıldığını görüyorum. Property dediğimiz kavramı tanıdığınız zaman umuyorum ki bu kodları okumakta daha az zorluk çekeceksiniz.

O halde başlıyoruz…

Property dediğimiz şey değişkenlere çok benzemekte. İsterseniz çok basit bir property örneği görelim ve bu örnek üzerinden ilerleyelim:

private int saglik = 100;
 
public int Saglik
{
	get
	{
		return saglik;
	}
	set
	{
		saglik = value;
	}
}

Bu örnek kodumuzdaki property’miz “Saglik” (büyük harfle başlayan). Syntax biraz garip gelebilir, başta bana da garip gelmişti. Bir property’i tanımlarken tıpkı değişkenlerdeki gibi property’nin erişilebilirliğini (public), türünü (int) ve ismini (Saglik) giriyoruz. Burada illa “saglik”ın ilk harfini büyültmek zorunda değiliz, istersek property’e “Health” veya “health” adını da verebiliriz.

Property’lerin içine girebileceğimiz sadece ve sadece iki fonksiyon bulunmakta: get ve set fonksiyonları. Ne zaman ki “Saglik” property’sine bir yerlerden erişmeye çalışırız, işte o zaman get fonksiyonu çağrılır. Ne zaman ki “Saglik” property’sine bir değer vermeye çalışırız, işte o zaman da set fonksiyonu çağrılır. Örneğin “Saglik = 50;” kodu yazacak olursam Saglik property’sinin set fonksiyonu çağrılır ve “value” dediğimiz özel değişken değer olarak 50 alır. Bu değer de “saglik = value;” kodu vasıtasıyla saglik’a aktarılır. Eğer ki “Debug.Log( Saglik );” yazacak olursam da Saglik property’sinin get fonksiyonu çağrılır ve “return saglik;” kodu vasıtasıyla “saglik” değişkeninde depolanan değer döndürülür.

Şu anda bu property’e hiç gerek yoktu, niye sadece saglik’i public yapmadık diyebilirsiniz. Dediğiniz şeyde tamamen haklısınız. Bu örnek için aslında bir property’e ihtiyacımız yoktu; direkt saglik’i public yapıp onun değeriyle oynayabilirdik. Ancak gelin şimdi şu örneğe bakalım:

public int tecrube = 0;
 
public int Seviye
{
	get
	{
		return tecrube / 100;
	}
}

Property’lerde olup da değişkenlerde olmayan başlıca iki özelliği bu örnekte görüyoruz:

1) Seviye property’mizin bir set fonksiyonu yok ama sadece get fonksiyonu var. Bu da demek oluyor ki kodlarımızda “Debug.Log( Seviye );” yazıp get fonksiyonunu çağırabiliriz ancak “Seviye = 10;” yazamayız zira Seviye property’sinin set fonksiyonu yok. Eğer ki bir değişkenin sadece değerini okumak istiyor ancak bu değerin elle değiştirilmesini istemiyorsanız property’ler sizin için biçilmiş kaftan. Eğer ki get fonksiyonunu silip set fonksiyonu yazsaydık bu sefer de “Debug.Log( Seviye );” yapamaz ancak “Seviye = 10;” yapabilirdik.

2) get fonksiyonunun gerçekten de bir fonksiyon olduğu dikkatinizi çekti mi? Direkt “return tecrube;” demek yerine “return tecrube / 100;” yazdık. Eğer ki her 100 tecrübe puanı kazandığımızda seviye atlıyorsak artık bu seviyeye erişmek için elimizde çok pratik bir property’miz bulunmakta! Eğer dilersek get fonksiyonunun içine istediğimiz kadar satır ekleyebilir, bu fonksiyon içinde başka fonksiyonları da çağırabiliriz. Çünkü dediğim gibi; get ve set gerçek birer fonksiyon gibi görev yapmakta.

Bu maddelere ilaveten, property’lerin bir başka özelliği de, get veya set fonksiyonlarının görünürlüğünü private veya protected yapabilmektir. Varsayılan olarak bu fonksiyonlar, property’nin görünürlüğü (bu örnekte public) ile aynı görünürlüğe sahiptirler ve tüm class’lar tarafından çağrılabilirler. Ancak diyelim ki property’e değer atamayı sadece property’nin tanımlandığı class yapabilsin istiyorsanız (yani diğer class’lar property’nin değerini değiştiremesin istiyorsanız), set fonksiyonunu private set olarak değiştirebilirsiniz. Aynı şeyi isterseniz get için de yapabilirsiniz.

Biraz daha gelişmiş bir örneğe bakalım. Diyelim ki bir GameObject‘in Rigidbody‘sine her seferinde GetComponent(Rigidbody) şeklinde erişmek yerine direkt RigidbodyComponent şeklinde erişmek ve eğer o sırada objede Rigidbody yoksa otomatik olarak bir Rigidbody eklemek istiyorsunuz. O halde şöyle bir property kullanabilirsiniz:

// Degisken
private Rigidbody rigidbodyComponenti;
 
// Property
public Rigidbody RigidbodyComponent
{
	// Rigidbody'e erismeye calisinca get çağrılır
	get
	{
		// Eğer ki rigidbodyComponenti'nin bir değeri yoksa
		if( rigidbodyComponenti == null )
		{
			// Rigidbody component'ini rigidbodyComponenti değişkeninde depola
			rigidbodyComponenti = GetComponent<Rigidbody>();
			 
			// Objede Rigidbody yoksa bir tane ekle
			if( rigidbodyComponenti == null )
				rigidbodyComponenti = gameObject.AddComponent<Rigidbody>() as Rigidbody;
		}
		 
		// rigidbodyComponenti'nin değerini (yani Rigidbody component'ini) döndür
		return rigidbodyComponenti;
	}
}

Gördüğünüz gibi get fonksiyonu birden çok satırdan oluşabiliyor ve de bu fonksiyon içerisinde başka fonksiyonları çağırabiliyoruz.

Son olarak da şu örneği inceleyelim:

// Bir UI Text objesi
public Text paraText;

// Degisken
private int para;
  
// Property
public int Para
{
	get
	{
		return para;
	}
	set
	{
		// para'nın değerini güncelle
		para = value;

		// Ekranda gösterilen para değerini (paraText) de güncelle
		paraText.text = para.ToString();
	}
}

Gördüğünüz üzere, belli bir değişkenin değeri her değiştiğinde bir kod çalıştırmak istiyorsanız, o değişken için bir property oluşturup istediğiniz kodu bu property’nin set fonksiyonuna yazabilirsiniz. Ancak bundan böyle bu değişkenin değerini değiştirirken property’i kullanmayı unutmayın (yani Para=10; yapın, para=10; değil).

NOT1: Bazen bir kodu incelerken şöyle tanımlanmış property’ler görebilirsiniz:

public float Degisken1 { get; set; }
 
// Bu property'e diğer class'lar değer atayamaz
public int Degisken2 { get; private set; }

Bunlar property tanımlamanın kısayollarıdır ve şu property’ler ile aynı görevi görürler:

private float degisken1;
public float Degisken1
{
	get { return degisken1; }
	set { degisken1 = value; }
}
 
private int degisken2;
public int Degisken2
{
	get { return degisken2; }
	private set { degisken2 = value; }
}

NOT2: Ender de olsa şu tarz property’lere rast gelebilirsiniz:

public class TestClass
{
	private string[] array;
	public string this[int index]
	{
		// array'in girilen index'teki elemanına dışarıdan erişebilmeyi sağlar
		get { return array[index]; }
		private set { array[index] = value; }
	}

	public Component this[string objeIsmi, System.Type componentTuru]
	{
		get
		{
			// objeIsmi isimli objedeki componentTuru'ne sahip Component'i bul ve döndür
			return GameObject.Find( objeIsmi ).GetComponent( componentTuru );
		}
	}
}

Bu tarz property’lere indexer denir. Bu property’ler bir veya daha çok parametre alırlar (ilk property’de “int index“, ikinci property’de “string objeIsmi” ve “Type componentTuru“). Bu parametrelerin türü ve ismi herhangi bir şey olabilir. Ardından property’nin get ve set fonksiyonlarında bu parametreleri kullanarak bir değer döndürebilir veya bir değer ataması yapabilirsiniz. Son olarak da, bu property’leri şu şekilde çağırabilirsiniz:

TestClass birObje = blabla;

// İlk indexer
string arrayIlkEleman = birObje[0];
// İkinci indexer
Component playerComponent = birObje["AnaKarakter", typeof( PlayerScript )];

Umarım ders faydalı olmuştur. Bir sonraki derste görüşmek dileğiyle!

yorum
  1. Kaan dedi ki:

    Yasir bey merhaba, aklıma bir şey takıldı. Propetylerin kullanım amacı update ile yapılacak işlemleri sadece değer değiştiğinde yapmak mı? Yani updatein sürekli çalışma prensibine benzer ama değer değiştiğin de mi çalışır?

Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.