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!
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?
Evet bunun için kullanabilirsiniz.