سلام و ممنون از توضیحات کامل تون آقا علی
درباره آرایه ها سئوال داشتم
نمیشه jaged array ها (آرایه در آرایه) رو کاری کرد که در حلقه ای ، اتوماتیک مثل آرایه های چند بُعدی ، تمام مقادیرشو برگردونه؟ مثل آرایه های چند بُعدی که با حلقه foreach تمام مقادیرشون رو اتوماتیک میشه بدست آورد
مثلا در این نوع ، آرایه ی زیر چجوری میشه این کار رو کرد؟ :
کد:
int[][][] NewMyArray = new int[3][][];
NewMyArray[0] = new int[2][];
NewMyArray[1] = new int[4][];
NewMyArray[2] = new int[2][];
NewMyArray[0][0] = new int[2];
NewMyArray[1][0] = new int[2];
NewMyArray[2][0] = new int[1];
NewMyArray[0][0][0] = 10;
NewMyArray[0][0][1] = 20;
NewMyArray[1][0][0] = 30;
NewMyArray[1][0][1] = 40;
NewMyArray[2][0][0] = 50;
چرا، شدنش که میشه، باید برای اون آرایه تون یک کلاس مجزا بسازید و برای کلاس تون یک کلاس IEnumerator هم بسازید که عضو هاش رو به ترتیب ارائه کنه و بعد برای کلاس اصلی تون IEnumerable رو پیاده سازی کنید و از کلاس IEnumerator ای که ساخته اید شی بسازید و تحویل بدهید.
توی این تاپیک نمیشه بهش پرداخته بشه، مطلب زیاد داره. در صورت تمایل برایش یک تاپیک مجزا ایجاد کنید.
پس این طور که فهمیدم اولین کلاس اصل بر آشکار سازیش هست و هر چی که داخل کلاس قرار میگیره حالا چه میخواد کلاس دیگه ای داخل این کلاس باشه یا هر چیز دیگه ای که در کلاس قرار گرفتنی هست مثل متد و متغییر و پروپرتی و ... اصل بر پنهان سازی شونه غیر از اینکه ما سطح دسترسی شونو مشخص کنیم
درسته؟
اصلی به نام آشکار سازی نداریم، هدف فقط پنهان سازی ئه، اما پنهان سازی از خود برنامه نویس معنی نداره. وقتی به حدی از پنهان سازی برسیم که خود برنامه نویس هم نتونه از کلاسش استفاده کنه، نتیجه می گیریم
که سطح درستی انتخاب نشده، پس یک درجه پنهان سازی رو کم می کنیم. یا مثلا شما می خواهید برای من یک کتابخانه توابع بسازید، اگر توابع رو private بسازید من نمی توانم ازش استفاده کنم، پس آنها را public می کنید،
این به معنای این نیست که وقتی برای کسی کتابخانه توابع می نویسید اصل بر آشکار سازی باشه. چون ناچار هستید سطح پنهان سازی رو تقلیل می دهید.
پس اگه اشتباه نکنم نکته ی آخر اینجا مهمه که گفتین : تنها جایی مجبور به مشخص کردن صریح فضای نام هستید که یک نام مشابه رو در چندین فضای نام دارید و کامپایلر دچار تردید شده.
بله.
من خوب متوجه نشدم . الان مگه وقتی شی ایجاد میکنیم ، در واقع داریم نوع داده ای مشخص میکنیم مگه؟ پس چرا بجای نام کلاس که نوع داده ای نیست ، تعیین کننده ی نوع داده ای که var هست گذاشتین؟
دارید دو تا کار رو با هم انجام می دهید، شما شیء ای تعریف می کنید که متغیرش قبلا معرفی نشده و بهش مقدار مشخصی هم می دهید. var از روی نوع مقدار می تونه تشخیص بده که متغیر از چه نوعی ئه،
فرضا وقتی مقدار "Sample" را داخل متغیر s قرار می دهید، var می تونه تشخیص بده که نوع داده string برای متغیر شما مناسبه. دیگه لزومی نداره که صریحا مشخص کنید که s یک متغیر از نوع string است.
من این کد رو متوجه نشدم یعنی کار توابع و مقادیر آرگومان هاش رو متوجه نشدم مخصوصا مسیر یا متدی که در خط اول در کلوشه فراخونی کردین چیه قضیه اش؟ توی تنها کلوشه هم مگه چیزی میزارن؟ فایل winmm.dll هم باید به پروژه add reference کنم اول؟ اگه آره در کجا وجود داره؟ یعنی توی ویندوز هست یا باید دانلود کنم؟
کلا صفات رو در بین [ و ] قرار می دهند و صفات از قبل تعریف شده هم خیلی زیاد اند و شما هم می توانید صفت جدید بسازید و ساختارش رو هم شما خودتون تعیین می کنید. بنابر این هر عبارتی که بین [ و ] قرار گرفته ممکنه براتون ناشناخته باشه.
این DllImport هم یک صفت از پیش تعریف شده ویژوال استدیو است که جزئی از فضای نام System.Runtime.InteropServices ئه.
سطر پایینی اش برای تعریف کردن یک تابع ئه که در winmm.dll پیاده سازی شده، دقت کنید که تعریف تابع یک عبارت کلیدی extern داره. extern یعنی این تابع رو شما پیاده سازی نمی کنید و کامپایلر داخل برنامه شما دنبال پیاده سازی اش نگرده، به فایل winmm.dll رجوع می کنه.
کتابخانه ای که با extern توابع اش رو تعریف می کنید نیازی به reference نداره و کاری هم با reference ای که می سازید ندارند. حتی معمولا اینجور کتابخانه ها اصلا اطلاعاتی که بشه بهشون reference داد ندارند.
winmm.dll جزئی از ویندوز تون ئه، احتمالا بخشی از فایل های Windows Media Player است که بصورت پیشفرض در ویندوز های اروپایی ویرایش N نیست.
یه سئوال دیگه اینکه من بیشتر کارم برای حوضه ی مالیتی مدیاست . یه چند تا کلاس که پروپرتی و متدهای زیاد و بسیار کاربردی در این حوضه باشه چی ها هستن تا بررسی شون کنم؟
البته مالتی مدیا که میگم نه اینکه در حد پلی کردن آهنگ باشه که اینها بخش کوچیک و فقط برای پلیر مالتی مدیا هست . بیشتر منظورم توابع هایی هست در حوضه ی رمزنگاری فایل ها و کار با درایوهای my computer و کار با فایل ها (کپی و حذف و اجرای فایل در administrator و مجوز دسترسی برای فایل ست کردن و...) و کار با فولدر و کار با اینترنت مثل دانلود فایل و ارسال ایمیل و کار با سرویس ها و پروسس های ویندوز و گرفتن اطلاعات سیستم سخت افزار و سیستم عامل (مثل نوع سیستم عامل و ساعت و تاریخ و ...) و کار با فایل های rar و ... و در کل مجموع توابع و پروپرتی ای که بالای 300 تا 1000 تا در این حوضه بشه و در کل از نرم افزار AMS که در این حوضه توابع داره بیشتر و بهتر بشه
شما کلا باید NET Framework. رو در MSDN بصورت کامل بررسی کنید. یک مواردی مثل کار با فایل های rar ربطی به خود سیستم عامل ندارند و باید از کتابخانه ها و ابزار های دیگر استفاده کنید.
و اینکه مهمترین سئوالم اینه که یک یا چند متد میخوام که اولا بتونه کنترلی ایجاد کنه (یعنی مثلا کاربر روی دکمه ای کلیک کرد ، یک شی ای که من میخوام میخوام مثل شی tree ایجاد شه) و دوما بتونه توی هر رویدادی از کنترل ها کدی اضافه کنه یا کل کدهای قبلی ای که نوشته شده داخل اون رویداد رو حذف و کد جدید را جایگزین کنه . این قضیه چجوری میشه توی #C ؟
#C یک زبان مفسری نیست که بتوانید هر جا که خواستید در حین اجرای برنامه بصورت پویا کد جدید بنویسید و اجرا کنید. بنابر این باید از قبل برای هر شرایطی کد نوشته باشید و تا در حین اجرا در صورت لزوم فراخوانی شان کنید.
اگر ویژوال استدیو نصب باشد با کمک یکسری روتین های خاص Net Framework. می توانید در حین اجرای برنامه پروژه جدیدی بسازید و کامپایل و اجرا کنید ولی برای این منظور قابل استفاده نیست که کد های یک رویداد رو از نو بنویسید.
ساختن متغیر و تخصیص شی جدید و مشخص کردن موقعیت و ابعاد و قرار دادن فرم فعلی به عنوان Parent اش :
کد:
[COLOR="#A9A9A9"] private void button1_Click(object sender, EventArgs e)
{[/COLOR]
var t = new TextBox();
t.Bounds = new Rectangle(10, 10, 100, 23);
t.Parent = this;
[COLOR="#A9A9A9"] }[/COLOR]
شما می توانید قبل یا در حین اجرای برنامه یک روتین رو به یک رخداد مشخص بچسبانید تا با وقوع رخداد اجرا شود یا جدا کنید تا اجرا نشود ولی نمی توانید کد آن روتین را در حین اجرای برنامه عوض کنید.
آن روتین موقع کامپایل شدن پروژه تعریف شده و دیگه کدش عوض نمیشه. اما می توانید در حین اجرای برنامه روتین یا روتین هایی که یک رخداد اجرا می کنه رو تعویض کنید.
کد:
button1.Click += new EventHandler([B][COLOR="#0000FF"]MyClick[/COLOR][/B]);
کد:
button1.Click -= new EventHandler([B][COLOR="#0000FF"]MyClick[/COLOR][/B]);
کد:
void [B][COLOR="#0000FF"]MyClick[/COLOR][/B](object sender, EventArgs e)
{
BackColor = Color.Red;
}
و می توانید برای شیء جدید دکمه ای که روی فرم قرار می دهید هم رخداد Click را به یک روتین متصل کنید :
کد:
var b = new Button();
b.Parent = this;
b.Click += new EventHandler(MyClick);
برای یاد آوری خودم ، فرق or باینری (یک علامت) اینه که همه ی شرط ها اجرا میشه ولی دو علامت که or شرطی هست به محظ غلط بودن اولین شرط ، بقیه رو چک نمیکنه
دقت کنید که در #C یک or منطقی با or باینری فرق داره. شما دارید or منطقی رو تعریف می کنید که البته تعریف تون درسته، ولی or باینری کاری با شرط نداره، محاسبه بیتی و باینری می کنه.
درسته که علامت or باینری و منطقی هر دو شون | ئه و از نظر پیاده سازی داخلی هر دو شون بر پایه محاسبات بیتی اند، ولی در زبان #C این دو عملگر تفکیک شده اند.
وقتی عملگر | در مورد ارقام صحیح بکار میشه Or باینری و وقتی در مورد bool ها بکار برده میشه Or منطقی ئه. || عملگر Or منطقی شرطی ئه. هم منطقی ئه و هم شرطی.
ولی چرا حالا اینجا or شرطی اصلا کامپایلر موقع نوشتن کد نمیزاره بنویسیم؟ خوب درسته که or شرطی جواب نمیده ولی این جواب ندادن باید موقع اجرای کد باشه نه اینکه موقع نوشتن کد نزاره بنویسیم
کامپایلر || رو فقط برای انواع داده ای که عملگر || رو تعریف کرده اند می تونه بفهمه، برای enum ها عملگر || تعریف نشده. مفهوم منطقی هم نداره. مقداری مثل Keys.E از نظر منطق زبان شرط نیست که برقرار باشه یا نباشه.
و سئوال دیگه اینکه پس من چرا با علامت اند (&&) در کد زیر جواب گرفتم ولی در کدی که شما دادین با اند جواب نمیده؟ یعنی کد زیر دقیق کار کد شما رو میکنه :
کد:
if(e.Control && e.KeyCode == Keys.E)
{
MessageBox.Show("control+E pressed");
}
if (e.KeyCode == Keys.A)
{
MessageBox.Show(e.KeyCode.ToString()+" Pressed");
}
دلیلش تفاوت بین KeyCode و KeyData است. KeyCode صرفا مقدار یک کلید رو که بخاطر اون رخداد فراخوانی شده رو میده، ولی KeyData شامل تمامی کلید های فشرده شده است.