PDA

View Full Version : تفاوت میان پراپرتی و متغیر عمومی



csharpcollegian
پنج شنبه 26 اسفند 1395, 23:12 عصر
سلام دوستان وقتتون به خیر
سال نو رو پیشاپیش تبریک میگم
دوستان من توو یه مقاله خوندم که متغیرهای عمومی یک کلاس بار زیادی روی سرور دارن و بهتره که به جای اون ها از پراپرتی ها استفاده بشه !
پس با این حساب دقیقا کاربرد متغیرهای عمومی چیه و تحت چه شرایطی نسبت به پراپرتی ها برتری دارن ؟
خیلی ممنونم

hadiroosta
جمعه 27 اسفند 1395, 10:02 صبح
یکی از اولین ارکان شی گرایی کپسولیشن هست و شما با تعریف متغییر به صورت عمومی این اصل مهم را نقض میکنید و در این صورت شی شما بسیار ناپایدار خواهد بود و احتمال به وجود امدن باگ در برنامه بالا خواهد رفت پراپرتی ها برای این که یه متغیر ها ی درون شی دسترسی داشته باشیم و همچنین اصل اول شی گرایی نقض نشه به وجود امده اند .

csharpcollegian
جمعه 27 اسفند 1395, 11:58 صبح
ممنونم دوست عزیز متوجهم چی می گید اما خب بالاخره بعضی اوقات بایستی از متغیرهای عمومی استفاده بشه، که راه بهترش استفاده از پراپرتی هاست.
اما خب می خوام بدونم با وجود پراپرتی ها اصلا ممکن هستش شرایطی پیش بیاد که استفاده از متغیرهای عمومی نسبت به پراپرتی ها بهینه تر و مناسب تر باشه ؟

hadiroosta
جمعه 27 اسفند 1395, 16:11 عصر
شما اگر دقت کنید به طور مثال وقتی میخواهید یک متغیر برای یک کلاس تعریف کنید که فقط قابلیت خواندن داشته باشه مجبور هستین از پراپرتی ها استفاده کنید و این اهمیت پراپرتی ها رو نشون میده ولی برای این که این پراپرتی از همه جا قابل دسترس باشه باید اون رو public می کنید و این اهمیت عمومی بودن را نشون میده و این دو تعریف هیچکدام به تنهایی به صورت بهینه قابل استفاده نیستند (با توجه به معایبی که ایجاد میکنند )
ترکیب این دو تعریف مشکل گشای دسترسی در شی گرایی هست .

alireza_s_84
جمعه 27 اسفند 1395, 17:27 عصر
سلام دوستان وقتتون به خیر
سال نو رو پیشاپیش تبریک میگم
دوستان من توو یه مقاله خوندم که متغیرهای عمومی یک کلاس بار زیادی روی سرور دارن و بهتره که به جای اون ها از پراپرتی ها استفاده بشه !
پس با این حساب دقیقا کاربرد متغیرهای عمومی چیه و تحت چه شرایطی نسبت به پراپرتی ها برتری دارن ؟
خیلی ممنونم
ازلحاظ کارایی این دو هیچ تفاوتی باهم ندارن و جمله "متغیرهای عمومی یک کلاس بار زیادی روی سرور دارن" هیچ معنا و مفهومی نداره.
جدا از مفاهیم شیی گرایی که دوستمون فرمودن تنها تفاوت این دو خلاصه میشه در نحوه دسترسی در رفلکشن و اینکه فیلدهای عمومی (همون متغیرهای عمومی شما) قابلیت شرکت در مقیدسازی داده ها (Data Binding) رو ندارن.
از اونجایی که فیلدهای عمومی همیشه قابل پیاده سازی از طریق پراپرتی ها هستن پس بهتره از اونها استفاده نکنید. حداقل بخاطر مسائل کپسوله سازی.

CsharpNevisi
یک شنبه 29 اسفند 1395, 11:06 صبح
شما برای پراپرتی ها میتونید لاجیک داشته باشید ولی برای فیلد باید یه متد بنویسید تا بتونید لاجیک داشته باشید ... دوتا مثال میزنم که کامل توش مشخصه که کجا فیلد مناسبه کجا پراپرتی :

خب ما میخواهم راجب اصل 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();
و مشکل حل میشه , ولی خب پراپرتی به تنهایی جواب کار مارو نداد

من پیشنهاد میکنم همیشه از پراپرتی استفاده کنید , چون مدیریت و انعطاف خیلی بیشتری دارند و حداقلش اینه که میتونید رفرنسش به جاهای مختلفو ببینید :
144713

csharpcollegian
یک شنبه 29 اسفند 1395, 11:48 صبح
جناب CsharpNevisi عزیز بابت توضیح خوب و وقتی که گذاشتین ازتون ممنونم