PDA

View Full Version : فرم استاتیک



alireza_tavakol
سه شنبه 17 مهر 1386, 16:48 عصر
یه سوال کاملا احمقانه
دوستان من میخوام با فرم های #C مثل فرم های توی VB کار کنم
یعنی نمی خواهم یه نمونه از فرم هام ایجاد کنم و بعد اون نمونه رو Show کنم
می خوام مستقیما بنویسم

Form1.show();
فکر کنم باید فرمم رو static تعریف کنم ولی نمیدونم چه طوری چه تغییری توی کلاس فرمم بدم تا فررمم استاتیک بشه
لطفا رهنماییی فرمایید با تشکر

jaza_sa
سه شنبه 17 مهر 1386, 16:58 عصر
من با vb آشنایی ندارم ولی میدونم میشه فرم رو نمایش داد بطوری که نمونه از اون نسازی

new frmTest().ShowDialog(this);

PC2st
سه شنبه 17 مهر 1386, 21:44 عصر
این سوال احمقانه نیست که هیچی، خیلی هم عاقلانه است :-)
مشکل اینجاست که اگر کلاستون (مثلا Form1) رو استاتیک تعریف کنید، دیگه نمیتونید از ارث بری استفاده کرده و در واقع کلاستون دیگه فرزند Form به حساب نمیاد. پس اگر بخواید بصورت استاتیک اون رو تعریف کنید، دیگه یک فرم بحساب نمیاد.

این سه راه حل رو در نظر داشته باشید:
1.


public static class MyNewForm1
{
private static readonly Form1 _coreForm = new Form1();
private class Form1 : Form
{
}
public static void Show()
{
_coreForm.Show();
}
}


2.


public class MyNewForm2 : Form
{
private readonly static MyNewForm2 _coreForm = new MyNewForm2();
private MyNewForm2()
{
}
public static void ShowMessage()
{
_coreForm.Show();
}
}

در این حالت مجبوریم بجای متد Show از نام ShowMessage استفاده کنم، چون متد Show از کلاس Form مخفی میشد و دیگه نمیشد بهش دسترسی پیدا کرد.

3. حالت سوم اینه که یک فیلد از نوع Form تعریف کنید و روی اون فیلد تغییرات رو اعمال کنید،
که این حالت روش سخت تری به نسبت حالت 1 و 2 است و البته حالت زیاد مناسبی هم نیست :-)

PC2st
چهارشنبه 18 مهر 1386, 04:40 صبح
در این حالت مجبوریم بجای متد Show از نام ShowMessage استفاده کنم، چون متد Show از کلاس Form مخفی میشد و دیگه نمیشد بهش دسترسی پیدا کرد.
متاسفانه فکر کنم دیشب قاطی بودم که این جمله رو نوشتم!
عذر میخوام... :افسرده: مجبور نیستم و میشد اینطوری نوشت:


public static void Show()
{
((Form)_coreForm).Show();
}

فکر کنم خودتون این رو میدونستید :-)

پی نوشت: روش دوم رو قبلا از طریق آرژنگ دیدم... طاقتم نمیگرفت، باید این رو میگفتم :-)

mohammad272005
چهارشنبه 18 مهر 1386, 04:54 صبح
البته من با جواب جناب PC2st.ir (http://barnamenevis.org/forum/member.php?u=30917) کاملا موافقم. فقط من روش lazy load رو که یه تفاوت خیلی کوچیک با مورد 2 داره ترجیح می‏دم. چون شاید کاربر حالا حالاها سراغ این خصوصیت نره ما یه فرم بلااستفاده بلافاصله بعد از بالا اومدن سیستم میسازیم که فقط باعث بالا رفتن میزان استفاده ما از حافظه می‏شه. خصوصا اگه بخوایم چندین فرم رو به این روش، load کنیم، مشکل نمایان‏تر میشه. من ترجیح می‏دم فیلد رو به read only property تبدیل کنیم و در اولین استفاده (که ممکن چند ساعت بعد از load شدن application ما باشه)، initializeش کنیم (sorry من فعلا vs ندارم پس کدهام عاری از اشکالا نیستن.)


privare static Form1 _form1;
public static Form1 Form1
{
get
{
if(_Form1 == null) _Form1 = new _Form1();
return _Form1;
}
}

alireza_tavakol
پنج شنبه 19 مهر 1386, 15:22 عصر
پس این چه منطق مزخرفی که نمیشه یک کلاس static از کلاس دیگه ای ارث بری بکنه ؟

PC2st
پنج شنبه 19 مهر 1386, 20:57 عصر
پس این چه منطق مزخرفی که نمیشه یک کلاس static از کلاس دیگه ای ارث بری بکنه ؟
چون اگر کلاسی مثل Form رو بصورت static تغییر بدیم، در واقع باید پیاده سازی اون هم کاملا تغییر پیدا کنه تا مثلا بشه از متد Show بصورت استاتیک استفاده کرد و زمانی میشه این متد رو static کرد که پیاده سازیش رو بصورت 100% تغییر بدیم و اگر هم کلاسهای static ارث بری داشتند، باز هم کمکی نمیتونستند بکنند.

mohammad272005
جمعه 20 مهر 1386, 02:56 صبح
پس این چه منطق مزخرفی که نمیشه یک کلاس static از کلاس دیگه ای ارث بری بکنه ؟عدم اطلاع از منطق چیزی، دلیل بر بی‏منطق بودن اون نیست.

alireza_tavakol
جمعه 20 مهر 1386, 03:23 صبح
حق با شماست من زیادی تند رفتم پوزش اینجانب حقیر رو بپذیرید

alireza_tavakol
شنبه 21 مهر 1386, 00:17 صبح
حالا دوستان میگن ادب رو رعایت کن راجب چیزی که نمیدونی بد دهنی نکن منم میگم چشم

اخه پس چرا کلاس static از یه کلاس static دیگه نمیتونه ارث بری بکنه

مرد میخوام جواب بده

اَرژنگ
شنبه 21 مهر 1386, 02:30 صبح
چرا کلاس static از یه کلاس static دیگه نمیتونه ارث بری بکنه


بستگی به مشکلی که میخواهید حل کنید راه‌هایه مختلف وجود دارند، استفاده زیادی از ارث بری هم خوب نیست و مشکلات دیگری ایجاد میکنه.

برایه اینکه ارث بری وجود داره دلیل نمیشه که هم جا ازش استفاده کرد، منتها یک مشکلی که برایه انسانها پیش میاد این است که وقتی که کار کردن با چکش را یاد میگیرند بعد از مدتی تمام مشکلات را میخواهند به صورت میخ‌ببینند.

از یک نظر دیگر طریقه تبدیل متدهایه استاتیک با متدهایی که میشه رونشتشان کرد برایه کامپیلر فرق میکنه و اگر که بخواهند همان قابلیتهایه متدهایی که را که میشه رونوشتشان کرد را به متدهاته استاتیک بدند مشکلاتی دیگری به وجود میاد (این تصور من است اگر کسی چیزه دیگری در این مورد میدانه که فکر میکنه این نظر درست نیست لطفا بفرسته).

البته مشکل اصلی این نیست که تمام درخواستهایه برنامه نویسان را نمیشه در یک زبان پیاده سازی کرد، بلکه اینکه برنامه نویسان قادر باشند که خصوصصیتهایه زبان را خودشان عوض کنند.

میشه کلی دلیل دیگر آٓورد که چرا استاتیک قابل ارث بری نیست مثلا اینکه کدهایی که استاتیک هسنتد بیشتر به زمان قبل از برنامه نویسی شئیگرا شبیه هستند. ارث بردن مفهومی است که در برنامه نویسی شئیگرا معنی دارد و بنابرین استفاده ازش در برنامه نویسی غیره شئیگرا درست نیست.

جواب واقعی به اینکه چرا ارث بری در سی‌شارپ برایه استاتیک وجود ندارد نمیشه داد، میشه کلی دلیل پیدا کرد که چرا باید بشه و اینکه چرا باید نشه. ولی در آخر همه این خصوصیت کنونی سی‌شارپ هست و ممکنه که یک روزی ارث بری را درش بگذارند (با دلیل و یا بی دلیل).

اگرچه ارث بری استاتیک مشکل شما را در این مورد سریع حل میکرد ولی حقیقت را برایه باید قبول کرد که الان نمیشه و از آٓنجا شروع کنید دنبال یک جواب و یا روش دیگر برایه این مسئله بگردید، شاید روش دیگر ،مزیاتی داشته باشد که از استفاده از ارث بری از استاتیک بهتر باشد.

alireza_tavakol
شنبه 21 مهر 1386, 03:11 صبح
ماشا الله شما کارت خیلی درسته
خیلی زحمت کشیدین اما من راضی نشم
من میگم حد اقل اگه یه کلاس استاتیک نمیتونه از یه کلاس غیر استاتیک ارث بری بکنه و علتش منطقی ( چون روش بحث شد ) اما چرا یه کلاس استاتیک نمی تونه از یه کلاس استاتیک ارث بری بکنه

اَرژنگ
شنبه 21 مهر 1386, 06:45 صبح
چرا یه کلاس استاتیک نمی تونه از یه کلاس استاتیک ارث بری بکنه

من سعی کردم که این را برسانم که دلیلی نداره، کسانی که سی شارپ را طراحی کردن بنابر دلایلی بر حسبه خودشان اینطوری پیاده کردند که نمیشه.
در زندگی خیلی چیزها هستش که اگر براش دنبال دلیل بگردید یک سری دلایل پیدا میکنید، و اگر بر ضدش دنبال دلایل بگردید باز پیدا میکنید.
فرض کنید که یکی از شما بپرسه چرا برنامه‌تان یک کاری را انجام میده و یا انجام نمیده، برایه هر دلیلی که بدید میشه چند تا دلیل بر ضدش پیدا کرد.
اگر دنبال دلایلی کسانی که سی‌شارپ را این این طوری طراحی کردند که استاتیک ارث نبره میگردید، این داستان دیگری‌است.
اگر سی شارپ جوری طراحی شده بود که یک کلاس استاتیک بتواند از یک کلاس استاتیک دیگر ارث بری کند، اونوقت یکی میپرسید که چرا کلاس استاتیک می تونه از یه کلاس استاتیک ارث بری بکنه.
اگر دنبال چرایه عمیقتری میگردید در این زمینه ممکنه وجود نداشته باشه، سی شارپ یک زبانی که یک عده سره کردند و ماها استفاده میکنیم.
معمولانداشتن یک قابلیت در یک زبان برنامه نویسی به این دلیل است که طراهانش در گذشته دیدند که داشتن آٓن قابلیت بیشتر مشکل ایجاد کرده و به خودشان گفتند که نداشتن اون قابلیت از سواستفاده کردنش جلوگیری میکند.
برنامه نویسی از آسمان نازل نشده، یکسری آٓدم بنابر منطقی که برایه آٓنها معنی دارده تصمیم گرفتن چه قابلیتهایی مهمه و چه قابلیتیهایی مهم نیست و حتا ممکن مضر باشه (حتی اگر بعضیها از ازش استفاده میکنند).
به نظر من نداشتن قابلیت ارث بری از کلاسهایه استاتیک مهم نیست، مشکلی که میخواد حل بشه چیه؟ جواب PC2st.ir مگر چی کم داره؟ این کاری که میخواهید اجنام بدید با سینگلتن پترن هم به راحتی انجام میشه، و بیلدر و کلاس فاکتوری هم بدرد این کار میخورند.

اَرژنگ
شنبه 21 مهر 1386, 11:52 صبح
شاید این کمکی باشد:
http://www.informit.com/articles/article.aspx?p=423349&seqNum=5&rl=1

PC2st
شنبه 21 مهر 1386, 22:22 عصر
بر اساس جوابی که آرژنگ دادند، بنابر صلاحدید طراحان سی شارپ، این قابلیت در این زبان وجود نداره حالا ممکنه عواقب مثبت یا عواقبی منفی داشته باشه...

+ دلایل نیاز نبودن به ارث بری:
1. همانطور که اطلاع دارید، وقتی که یک کلاس بصورت static باشه، در واقع فقط یک نمونه از آن کلاس میتونه وجود داشته باشه، مثلا اگر کلاس A استاتیک باشه و کلاس B بصورت غیر استاتیک، رفتار زیر رو انتظار خواهیم داشت:


B b1 = new B();
B b2 = new B();
B b3 = new B();

A.X();
b1.X();
b2.X();
b3.X();

همانطور که انتظار داشتید، متد X از کلاس A، فقط روی یک نمونه شی میتونه صدا زده بشه ولی متد X از کلاس B میتونه روی چندین شی صدا زده بشه که در کدهای فوق، متد X از کلاس B روی سه نمونه شیئ متفاوت، صدا زده شده است. اما متد X از کلاس A فقط روی یک نمونه شیئ میتونه صدا زده بشه و اون نمونه شیئ چیزی نیست جز خود کلاس A.
پس وقتی مبحث ارث بری (inherit) عنوان میشه، نمونه اشیاء متفاوت هم در نظر گرفته میشوند. یعنی وقتی که من از یک کلاس مشتق میکنم و از کلمه کلیدی base استفاده میکنم، مطمئن نیستم که base فقط به یک شی اشاره داره و در واقع کلمه کلیدی base میتونه به هر نمونه شیئ اشاره کنه (کدهای فوق رو به یاد بیارید که b1 و b2 و ... سه نمونه شیئ متفاوت هستند). اما در کلاس استاتیک بحث فرق میکنه و فقط یک نمونه شیئ وجود داره و وقتی من مثلا مینویسم A.X، مطمئن هستم که متد X روی نمونه شی منحصر به فردی که انتظارش رو داشتم صدا زده میشه. پس در یک کلاس استاتیک، به کلمه کلیدی مثل base لازم نیست، چون فقط یک نمونه شیئ از کلاس استاتیک وجود داره و من میتونم با نوشتن کلمه A به اون نمونه شیئ دسترسی داشته باشم و مطمئن باشم که نمونه شیئ دیگری وجود نداشته باشه. (البته base همان نمونه شیئ this است ولی اعضای override نشده رو صدا میزنه)
بر این اساس، بجای کلمه کلیدی base میشه از نام کلاس استاتیک استفاده کرد.

2. اگر به فرض میشد از یک کلاس استاتیک توسط کلاس استاتیک دیگری ارث بری کرد، اما بدلیل ماهیت استاتیک بودن کلاس، نمیشد از روابط والد و فرزند به نحو احسنت سود برد، چون مثلا اگر کلاس استاتیک B از کلاس استاتیک A به ارث رسیده باشد:


object o = new Control();
A a = B;

خط اول بدون مشکل خواهد بود ولی خط دوم غیر قابل قبول خواهد شد چون تنها توسط یک شیئ میتوان به کلاس استاتیک A یا B دست یافت و ایجاد اشیاء مختلف برای کلاسهای استاتیک قابل قبول نیست، پس نمیشد یک کلاس فرزند رو در شیئ ای از نوع کلاس والد قرار داد. برای تشبیه این موضوع، یک ArrayList رو در نظر بگیرید که نشه اشیاء فرزند object رو بهش اضافه کرد! و در اینصورت عملا یکی از مهمترین جنبه های ارث بری از بین خواهد رفت مگر اینکه ماهیت کلاس استاتیک تغییر پیدا کند که اگر اینطور شود، دیگر نیازی به کلاسهای استاتیک نیست :-)

+ دلایل نیاز به ارث بری: ممکنه دلائلی وجود داشته باشه ولی متاسفانه اطلاع ندارم.