شما برای پراپرتی ها میتونید لاجیک داشته باشید ولی برای فیلد باید یه متد بنویسید تا بتونید لاجیک داشته باشید ... دوتا مثال میزنم که کامل توش مشخصه که کجا فیلد مناسبه کجا پراپرتی :
خب ما میخواهم راجب اصل Liskov substitution principle (اصل سوم از 5 پنج اصل شی گرایی یا SOLID) صحبت کنیم :
این اصل میگه کلاس های فرزند باید بتوانند جایگزین کلاس های پدر شوند .
ما میخواییم دو تا کلاس مربع و مستطیل داشته باشیم .. این کدهای ماست :
یک کلاس پدر به صورت abstract :
public abstract class Shape{
public virtual int Width { get; set; }
public virtual int Height { get; set; }
}
و فرزندان از اون ارث بری میکنند و مربع و مستطیل به این شکل میشن
مربع :
public class Square : Shape{
public override int Width
{
get{return base.Width;}
set
{
base.Height = value;
base.Width = value;
}
}
public override int Height
{
get{return base.Height;}
set
{
base.Height = value;
base.Width = value;
}
}
}
مستطیل :
public class Rectangle : Shape{
public int Width { get; set; }
public int Height { get; set; }
}
اگر دقت کرده باشید ما تو مربع گفتیم که هر موقع طول مقداردهی شد عرض هم مساوی طول قرار بده و بالعکس تا بتونیم مربع داشته باشیم ولی تو مستطیل نیازی نیست .. خب ما این کارو راحت با استفاده از پراپرتی ها انجام دادیم .. حالا اگر اینجا جای پراپرتی از فیلد استفاده مکردیم هیچ کنترلی روی طول و عرض نداشتیم .. (راه حل فیلد اینجاست که باید به صورت private تعریف شوند و با پراپرتی و یا تابع عملیات انتصاب صورت گیرد)
حالا اگر کلاس ما کاستوم کنترل شود و درون تولباکس قرار بگیره .. بعد از استفاده از اون روی فرم دیگه فیلد ها درون پنجره پراپرتیز نمایش داده نمیشن .. هرچند اگر پابلیک باشند .
خب حالا ما میخواییم الگوی طراحی SingleTone رو پیاده سازی کنیم تو حالت ThreadSafe .. این میشه کدهای ما :
public sealed class SingleTon {
private static volatile SingleTon Instance;
private static object _lock = new object();
private SingleTon() { }
public static SingleTon Getinstance()
{
if (Instance == null)
{
lock (_lock)
{
if (Instance == null)
Instance = new SingleTon();
}
}
return Instance;
}
public static InfoMe InfoP { get; }// = new InfoMe(); این امکان از سی شارپ 6 به بعد آمده است // VS2015
public static readonly InfoMe InfoF = new InfoMe();
}
خب ما فیلدهای رفرنس با نام InfoP و InfoF داریم , من میخوام بدون اینستنس گرفتن از کلاس از این دو پراپرتی استفاده کنم , از InfoF استفاده میکنم ولی InfoP قطعا Null pointer exception خواهد داد چون مقداردهی نشده و Null برمیگردونه , خب ما قبل از سی شارپ 6 میومدیم تو کانستراکتور مقدار دهی میکردیم و از سی شارپ 6 به بعد مستقیم این کارو میکنیم بدون کانستراکتور ولی این دو کار به شرطی هست که ما set هم داشته باشیم .. پس تو این شرایط پراپرتی به تنهایی جوابگو نیست و میتونیم کدهامون رو به این شکل تغییر بدیم :
public static InfoMe InfoP { get { return _infoF; } }
private static InfoMe _infoF = new InfoMe();
و مشکل حل میشه , ولی خب پراپرتی به تنهایی جواب کار مارو نداد
من پیشنهاد میکنم همیشه از پراپرتی استفاده کنید , چون مدیریت و انعطاف خیلی بیشتری دارند و حداقلش اینه که میتونید رفرنسش به جاهای مختلفو ببینید :
Untitled-1.png