رشته ها
در C یا ++C ساختار رشته به صورت ارایهای از نوع char بود که امکان اضافه کردن به رشته را محدود میکرد به دلیل ثابت بودن طول در آغاز تعریف ولی در سی شارپ دو نوع متفاوت رشته وجود دارد؛ که یکی به صورت آرایهای با طول ثابت ۲۵۶(در عمل ۲۵۵)موجوداست (به صورت پیش فرض) و در صورتی که با کمبود جا روبرو شود فضای جدید (بزرگتر) یافته و به ان انتقال میدهد؛ ولی در نوع دوم رشتهها از لیست پیوندی استفاده میشود.
***لیست پیوندی***
یست پیوندی (به انگلیسی: Linked list) ساختاری شامل دنبالهای از عناصر است که هر عنصر دارای اشارهگری به عنصر بعدی در دنباله است. فهرست پیوندی از جملهٔ سادهترین و رایجترین دادهساختارها است و در پیادهسازی از دادهساختارها پشته (Stack)، صف (Queue) و جدول درهمسازی (Hash table) استفاده میشود. مزیت مهم فهرست پیوندی نسبت به آرایهها این است که ترتیب قرار گرفتن دادهها در آن با ترتیب قرار گرفتن آنها در حافظه متفاوت است. به همین دلیل فهرست پیوندی دارای این ویژگی است که درج و حذف گرهها در هر نقطهای از فهرست، با تعداد ثابتی از عملیات امکانپذیر است. از طرف دیگر فهرست پیوندی اجازه دستیابی تصادفی به داده یا هرگونه اندیسگذاری را نمیدهد. در نتیجه بسیاری از اعمال ابتدایی نظیر به دست آوردن آخرین عنصر فهرست، پیدا کردن عنصر شامل داده مورد نظر، یا مشخص کردن مکان درج یک عنصر جدید ممکن است نیازمند بررسی اکثر عناصر فهرست باشد.
سی شارپ دارای یک سامانه نوع یکپارچهاست که به آن CTS میگویند. این بدان معناست که تمام انواع، شامل موارد اصلی مانند Integerها، مشتق شده از System.Object هستند. به عنوان مثال، هر نوع یک متد به نام ToString() را به ارث میبرد. بخاطر کارایی، انواع اولیه (و انواع مقداری) بهطور داخلی فضایی برای آنها بر روی پشته در نظر گرفته میشود.
انواع داده
CTS دادهها را به دو نوع تقسیم میکند:
نوع مقداری (Value Type)
نوع مرجعی (Refrence Type)
انواع دادهای توده سادهای از داده میباشند. نمونههای انواع دادهای نه هویت مرجعی دارند و نه مفاهیم مقایسه مراجع را. برای مقایسه برابری یا عدم برابری انواع دادهای، خود مقدار دادهها را با یکدیگر مقایسه میکنیم مگر اینکه عملگرهای مشابه دوباره تعریف شده باشند. مقادیر دادههای مرجعی همیشه یک مقدار پیشفرض دارند و همیشه میتوانند ایجاد یا کپی شوند. یکی دیگر از محدودیتهای انواع دادهای این ات که آنها نمیتوانند از یکدیگر مشتق شوند (ولی میتوانند اشتراکاتی داشته باشند) و هم چنین نمیتوانند در سازنده مقدار دهی اولیه شوند. مثالی از انواع دادهای، بعضی از انواع اولیه مانند int و float و char و System.DateTime میباشند. در مقابل، انواع مرجعی مفهوم تعریف مرجعی را دارند (که در آن هر نمونه از نوع مرجع، بهطور ذاتی از دیگر نمونهها جدا میشود، حتی اگر داده هر دو نمونه یکی باشد). این دقیقاً نمونه مشابه مقایسه تساوی یا عدم تساوی دادههای مرجعی است، که در آن آزمایش برای مرجعها از دادهایها سریع تر است. در کل نه همیشه امکان تعریف نمونه مرجعی وجود دارد و نه امکان کپی یا نمایش مقادیر مقایسه دو نمونه؛ ولی به هر حال انواع مرجعی خاص میتوانند این اعمال را از طریق سازندههای عمومی یا اجرای واسطهای مشابه (مثل ICloneable یا IComparable) انجام دهند. نمونههایی از انواع مرجعی، اشیاء، System.String و Sysmet.Array میباشند. هر دو نوع داده قابلیت انعطاف توسط تعریف به وسیله کاربر را دارند. در واقع وقتی ما نوع دادهای را به تابع ای ارسال میکنیم، آدرس داده نیز فرستاده میشود. البته این امر پیشفرض است ولی برای دادههای مثل آرایه، رشتهای، آدرس فرستاده میشود و ارسال از نوع مرجع میشود
Boxing و UnBoxing
Boxing عمل تبدیل مقدار نوع دادهای به نوع مرجع مشابه آن میباشد
مثال:
int foo = 42;// Value type... object bar = foo;// foo is boxed to bar. int foo = 42;// Value type. object bar = foo;// foo is boxed to bar. int foo2 = (int)bar;// Unboxed back to value type.
سی شارپ به برنامهنویس با استفاده از کلمه کلیدی Struct اجازه میدهد تا انواع مقداری User-defined را ایجاد کند. از دیدگاه برنامهنویسی، آنها کلاسهای سبک وزن به نظر میرسند. برخلاف کلاسها (که بر روی heap قرار میگیرند) و شبیه به انواع اولیه استاندارد مانند انواع مقداری Structها نیز بر روی پشته قرار میگیرند. آنها همچنین میتوانند قسمتی از یک شئ باشند، یا در یک آرایه مرتب شوند، بدون حافظه غیر مستقیمی که بهطور معمول برای انواع کلاس تخصیص مییابد
در اخرین نسخه از سی شارپ ویژگیهایی جدیدی به این زبان اضافه شده که چندتا شو براتون مینویسم
سی شارپ لوکال فانکشن C# Local Fanction
در طراحی کلاسها بعضی اوقات متدهایی تعریف می کنیم که فقط از یک جا فراخوانی می شوند و در واقع نمی خواهیم متد را در جاهای مختلف reuse کنیم. این متدها که معمولا private هستند برای ماجولاریتی و کوچک و خوانا شدن بدنه متد ایجاد میشوند. اما گاهی باعث میشوند در نگاه اول فهم منطق کلاس دشوار شود.
با قابلیت جدید local function که در سی شارپ 7 معرفی شده می توان یک متد را درون متد دیگر تعریف کرد. این موضوع باعث می شود، برنامه نویسی که کد رو میخواند متوجه شود متد فقط در یک جا مورد استفاده قرار گرفته و فهم آن از موضوع راحت تر خواهد بود.
سی شارپ (C# Tuples)
همانطور که میدانیم در سی شارپ برای تعریف یک تایپ میتوان از امکانات قدرتمندش همچون class و struct استفاده کرد. اما بعضی اوقات استفاده از این قابلیت ها نیازمند کار زیادی است و در نهایت هم مزیت کمی بهمراه دارد. ممکن است شما نیاز به تعریف متدی داشته باشید که یک ساختار ساده مثل چند فیلد داشته باشد. برای این سناریو C# مفهوم tuple را معرفی کرده است.
تاپل یک ساختمان داده ساده است که میتواند شامل چند فیلد باشد. این فیلدها اعتبارسنجی نمیشوند و نمیتوان متدی هم برای آن تعریف کرد. صرفا شامل تعریف چند متغیر میباشد. تاپل یک ساختار ساده و سبک برای تعریف ساختمان داده هایی است که بیش از یک مقدار دارند.
میتوان گفت تاپل یک گروه از متغیرهای موقتی هستند. تاپلها شبیه کلاس های POCO هستند اما به جای تعریف آنها به صورت یک کلاس، متغیر ها به صورت موقتی تعریف میشوند.
می توان یک تاپل را با مقدار دهی هر عضوش تعریف کرد.
var str= ("a", "b");
متغیرهای out در C# 7
معمولا وقتی بخواهیم یک متد چند مقدار را برگرداند از پارامتر out استفاده می کنیم. تا قبل از ارائه 7 #C، باید ابتدا متغیر out را تعریف میکردیم و سپس از آن به عنوان یک آرگومان تابع استفاده میکردیم، به عبارت دیگر قبلا برای ارسال یک پارامتر به صورت out به یک متد، باید قبل از استفاده به عنوان آرگومان ابتدا متغیر را تعریف میکردیم. در 7 #C امکان تعریف پارامتر، به صورت inline در محل ارسال آرگومان وجود دارد و دیگر نیازی به تعریف متغیر، قبل از ارسال آن به تابع نیست
int num; if (int.TryParse(input, out num)) WriteLine(num); else WriteLine("Could not parse input");
در سی شارپ 7 می توان متغیر out را در لیست آرگومان تابع تعریف کرد.
if (int.TryParse(input, out int result)) WriteLine(result); else WriteLine("Could not parse input");
بهینه سازی ساختار switch
قبل از بروز رسانی دستور بشکل زیر بود
object value = 2; var input = (int) value; switch (input) { case 1: break; case 2: break; case 3: case 4: case 5: break; }
ولی میتوان در سی شارپ7 بصورت زیر این دستور رو نوشت
object value = 2; switch(value) { case int input when input (1>=100): break; case int input when input(value<100 && value >=200): break; case int input when input >= 3 && input <= 5: break; }
بازگرداندن چندین مقدار در متدها
در سی شارپ 6 و ورژنهای پایین تر، برای اینکه بتوانیم از یک متد چندین خروجی بگیریم باید از روشهای زیر استفاده میکردیم
استفاده از پارامترهای out
استفاده از Tuple ها
استفاده از یک Class یا Struct
در سی شارپ 7 این کار به راحتی و به صورت قابل پیاده سازی است
(int, int) MyMethod(List<int> numbers) { // دستورات }
و همچنین میشه متدهای خروجی را نامگذاری کرد --بشکل زیر
(int Sum, int Substract) MyMethod(List<int> numbers) { // دستورات }
var numbers = new List<int>() { 2, 5, 6, 1, 5 }; var result = MyMethod(numbers); Console.WriteLine(result.Sum); Console.WriteLine(result.Substract);