درخواست های ارتباط
جستجو
لیست دوستان من
صندوق پیام
همه را دیدم
  • در حال دریافت لیست پیام ها
صندوق پیام
رویدادها
همه را دیدم
  • در حال دریافت لیست رویدادها
همه رویدادهای من
دوره های مرتبط
دوره آموزشی مقدماتی برنامه نویسی جاوا به زبان ساده
مدرس: مهدی عادلی
این دوره را در 17 قسط خریداری کنید
دوره آموزشی اسکریپت نویسی Batch یا Batch Scripting در ویندوز به زبان ساده
مدرس: حسین احمدی
این دوره را در 11 قسط خریداری کنید
دوره آموزشی برنامه نویسی پیشرفته زبان سی شارپ
مدرس: حسین احمدی
این دوره را در 78 قسط خریداری کنید
دوره تخصصی آموزش متن کاوی با ابزار NLTK
مدرس: taghandiki
این دوره را در 11 قسط خریداری کنید
دوره آموزشی پردازش متن با زبان برنامه نویسی پایتون
مدرس: taghandiki
این دوره را در 20 قسط خریداری کنید
دوره آموزشی برنامه نویسی اندروید با زبان جاوا به زبان ساده
مدرس: مهدی عادلی
این دوره را در 27 قسط خریداری کنید
دوره آموزشی برنامه نویسی حرفه ای پایتون به زبان ساده
مدرس: حسین احمدی
این دوره را در 23 قسط خریداری کنید
دوره آموزشی برنامه نویسی WPF در ویژوال استودیو
مدرس: Amirhossein Fazlikhani
این دوره را در 12 قسط خریداری کنید
دوره آموزشی برنامه نویسی به زبان پرل بصورت پروژه محور
مدرس: dr-iman
این دوره را در 13 قسط خریداری کنید
دوره آموزشی ساخت ربات تلگرام
مدرس: taghandiki
این دوره را در 8 قسط خریداری کنید

آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و هشتم :: نکات تکمیلی Generic ها، کلاس List و کلاس Dictionary

0 نظرات
306 بازدیدها
در ادامه مباحث آموزشی زبان سی شارپ، در این قسمت به بررسی نکات تکمیلی Generic ها پرداخته و با یکسری از کلاس های Generic موجود در کتابخانه دات نت آشنا می شویم. در ابتدا به بررسی Constraint ها خواهیم پرداخت که به ما اجازه اعمال محدودیت در نوع داده انتخابی برای جایگاه های Generic را می دهند. برای مثال، مد زیر را در نظر بگیرید:

public class GenericType<T>
{
    public T Property { get; set; }
}

گاهی وقت ها، نیاز داریم که زمان ساخت شئ، T در GenericType، تنها نوع داده ای که از نوع Value Type می باشد را قبول کند یا فقط Reference Type را قبول کند. برای اینکار، می توانیم از Constraint ها استفاده کنیم. برای استفاده از Constraint ها از کلمه کلیدی where استفاده می کنیم. انواع مختلفی از Constraint ها وجود دارد که در ادامه به بررسی آن ها خواهیم پرداخت.

1. نوع های داده مشتق شده از یک کلاس: بوسیله این قابلیت، می توان انتخاب کرد که یک پارامتر Generic، می بایست حتماً از یک کلاس مشخص مشتق شده باشد، به مثال زیر توجه کنید:

public class GenericType<T> where T : MyClass
{
    public T Property { get; set; }
}

با استفاده از کد بالا، می گوییم که تنها کلاس هایی را می توان به عنوان پارامتر جنریک T انتخاب کرد که از کلاس MyClass مشتق شده باشند. دقت کنید، ابتدا کلمه کلیدی where، سپس نام پارامتر جنریک و بعد از علامت کاراکتر :، نام کلاس نوشته شده است. دقت کنید که تنها می توان یک کلاس را برای این Constraint مشخص کرد.

2. نوع های داده ای که یک interface را پیاده سازی کرده اند: با کمک این Constraint، تنها نوع های داده ای را می توان برای یک Constraint انتخاب کرد که یک interface خاص را پیاده سازی کرده باشد:

public class GenericType<T> where T : IInterface1, IInterface2
{
    public T Property { get; set; }
}

شما می توانید یک یا چند interface را برای این Constraint انتخاب کنید. همچنین می توانید به صورت ترکیبی از نام یک کلاس و نام یک یا چند interface استفاده کنید:

public class GenericType<T> where T : MyClass, IInterface1, IInterface2
{
    public T Property { get; set; }
}

مزیت استفاده از این نوع Constraint ها چیست؟ زمانی که شما یک کلاس یا interface را به عنوان Constraint یک پارامتر Generic انتخاب می کنید، می توانید به اعضاء آن کلاس یا Interface ها در داخل آن کلاس دسترسی داشته باشید. برای مثال، نمونه کد زیر را در نظر بگیرید:

public interface IDiscount
{
    double CalculateTax();
}

public class Product : IDiscount
{
    public string Name { get; set; }
    public int Price { get; set; }

    public virtual double CalculateTax()
    {
        return 0;
    }
}

public class ProductManager<TProduct> where TProduct : Product
{
    public double CalculatePrice(TProduct product)
    {
        return product.Price - product.CalculateTax();
    }
}

به دلیل اینکه پارامتر TProduct از نوع IProduct و Product مشخص شده، می توان داخل کلاس ProductManager، به راحتی به خصوصیت Price و متد CalculateTax دسترسی داشت.

3. نوع های داده Value Type: در صورتی که از کلمه کلیدی struct برای Constraint یک پارامتر استفاده شود، تنها می توان از نوع های داده Value Type برای پارامتر ورودی جنریک استفاده کرد و در صورت استفاده از نوع های داده Reference Type، با پیغام خطا مواجه می شویم:

public class ValueHolder<T> where T : struct
{
    public T Value { get; set; }
}

4. نوع های داده Reference Type: در صورت نوشتن کلمه کلیدی class برای Constraint یک پارامتر، تنها می توان از نوع های داده Reference Type برای پارامتر ورودی جنریک استفاده کرد و بر عکس struct، در صورت استفاده از Value Type ها مانند int و float، پیغام خطا دریافت می کنیم:

public class ValueHolder<T> where T : class 
{
    public T Value { get; set; }
}

دقت کنید، امکان استفاده همزمان از Constraint های struct و class وجود ندارد، همچنین نمی توانید به صورت ترکیبی از struct یا class و مشخص کردن کلاس پایه برای پارامتر Generic استفاده کنید، اما می توانید به صورت ترکیبی از struct یا class و interface ها استفاده کنید. اما باید به اولویت ها دقت کنید، باید ابتدا کلمه کلیدی struct یا class را بنویسید و سپس نام interface ها را بنویسید:

public class ValueHolder<T> where T : struct, IInterface1, IInterface2
{
    public T Value { get; set; }
}

5. کلاس هایی که حتماً default constructor یا سازنده پیش فرض دارند:، در صورتی که به عنوان Constraint عبارت ()new را بنویسید، تنها از کلاس هایی می توانید استفاده کنید که سازنده پیش فرض داشته باشند. این Constraint می بایست، حتماً به عنوان آخرین Constraint نوشته شود:

public class ProductManager<TProduct> where TProduct : Product,new()
{
    public TProduct CreateProduct()
    {
        return new TProduct();
    }
}

در صورتی که در کد بالا، ()new را به عنوان Constraint ننویسیم، عبارت return new Product تولید خطا می کند، زیرا تنها در صورتی می توان اقدام به ساخت شئ کرد که نوع داده مشخص شده برای پارامتر Generic، دارای سازنده پیش فرض باشد.

6. مشخص کردن Constraint ها برای چندین پارامتر Generic: فرض کنید کلاسی که نوشتیم چندین پارامتر Generic دارد، برای مشخص کردن Constraint برای چندین پارامتر به صورت زیر عمل می کنیم:

public class GenericType<T1, T2> where T1 : class,new() where T2 : IEnumerable,new()
{
        
}

برای خوانایی بهتر کد بهتر است Constraint هر پارامتر در یک خط مجزا نوشته شود:

public class GenericType<T1, T2> 
    where T1 : class,new() 
    where T2 : IEnumerable,new()
{
        
}


آشنایی با کلاس جنریک List



در کتابخانه DotNet، تعداد زیادی از کلاس های Generic وجود دارند که هر یک کاربرد های خاص خود را دارند، در این بخش، ابتدا می خواهیم با کلاس List که یک کلاس Generic است آشنا شویم، اما قبل از آن بهتر است که با کلاسی با نام ArrayList آشنا شویم، کلاس ArrayList، کلاسی است غیر جنریک که به ما اجازه اضافه کردن انواع Data Type های مختلف را میدهد، این کلاس در فضای نام System.Collections قرار دارد. شیوه استفاده از این کلاس به صورت زیر است:

System.Collections.ArrayList list = new ArrayList();
list.Add(12);
list.Add("Hossein");
list.Add(4.5m);

Console.WriteLine((int) list[0]);
Console.WriteLine((string)list[2]);

Console.ReadKey();

همانطور که می بینید، مانند آرایه ها، می توان داخل یک ArrayList با کمک متد Add مقادیر مختلف را اضافه کرد و با Index مربوطه مقداری را از خانه مورد نظر خواند. اما مشکلی که در اینجا وجود دارد، پارامتر ورودی متد Add، از نوع Object است و زمان استفاده از داده های Value Type، عملیات Boxing و UnBoxing رخ می دهد، همچنین مکانیزم Type Safety در این کلاس وجود ندارد، زیرا می توان هر مقداری را داخل آن اضافه کرد و همچنین زمان خواندن مقدار می بایست عملیات Casting را انجام دهیم. در این لحظه کلاس List که یک کلاس Generic است و در فضای نام System.Collections.Generic قرار دارد وارد صحنه می شود. مکانیزم استفاده از این کلاس به صورت زیر است:

System.Collections.Generic.List<int> numbers = new List<int>();
numbers.Add(12);
numbers.Add(21);

Console.WriteLine(numbers[0]);

Console.ReadKey();

همانطور که مشاهده می کنید، زمان ایجاد شئ در کلاس List، ابتدا به عنوان پارامتر generic، نوع آیتم های لیست را مشخص می کنیم، حال متد Add تنها پارامترهای وردی از نوع int را قبول می کند و همچنین زمانی که مقداری را از یکی از خانه های List میخوانیم، مقدار برگشتی از نوع int خواهد بود. مشاهده می کنید که تمامی مشکلات موجود در کلاس ArrayList، بوسیله کلاس List برطرف شده اند. همچنین می توان بوسیله دستور foreach خانه های لیست را پیمایش کرد:

foreach (var number in numbers)
{
    Console.WriteLine(number);
}

برای حذف یک مقدار از لیست می توانید از متد Remove استفاده کنید:

numbers.Remove(12);

برای درج یک مقدار در لیست از متد Insert استفاده کنید که پارامتر اول ایندکس درج مقدار و پارامتر دوم مقدار مورد نظر برای درج می باشد:

numbers.Insert(1, 34);

بوسیله خاصیت Count می توانید تعداد آیتم های داخل لیست را بدست آورید:

var items = numbers.Count;

در صورتی که بخواهید مقداری را از یک ایندکس حذف کنید با دستور RemoveAt این کار امکان پذیر است، کافیست به عنوان پارامتر، ایندکس مورد نظر را مشخص کنید:

var items = numbers.RemoveAt(12);

دستورات دیگری نیز برای لیست ها وجود دارد که بررسی این دستورات را به عهده دوستان عزیز میگذارم.


کلاس Dictionary


این کلاس نیز یک کلاس Generic است و به شما این امکان را می دهد تا مقداری را به عمراه یک کلید در لیست ذخیره کنید و دسترسی به مقادیر بر اساس کلید خواهد بود. فرض کنید که لیستی از دانشجویان را می خواهیم ذخیره کنیم، ذخیره اطلاعات دانشجویان بر اساس شماره دانشجویی بوده و بعد می توانیم با کمک شماره دانشجویی به عنوان کلید، اطلاعات دانشجو را بازیابی کنیم، ابتدا کلاسی برای دانشجو تعریف می کنیم:

public class Student
{
    public Student(string studentId, string firstName, string lastName, byte age)
    {
        StudentId = studentId;
        FirstName = firstName;
        LastName = lastName;
        Age = age;
    }

    public string StudentId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public byte Age { get; set; }
}

در قدم بعدی، می توانیم با تعریف یک Dictionary اطلاعات دانشجو را به صورت زیر ذخیره کنیم:

Dictionary<string, Student> students = new Dictionary<string, Student>();
students.Add("10001", new Student("10001", "Hossein", "Ahmadi", 30));
students.Add("10002", new Student("10002", "Mohammad", "Nasiri", 30));

در خط اول یک شئ با نام Student از روی کلاس Dictionary ایجاد کردیم، همانطور که مشاهده می کنید، کلاس Dictionary دو پارامتر جنریک دارد، اولی برای کلید و دومی برای مقدار که در کد بالا، نوع string را برای کلید و نوع Student را برای مقدار مشخص کردیم. در قسمت های بعدی بوسیله دستور Add، با شناسه های 10001 و 10002 دو دانشجو به لیست اضافه شدند. پارامتر اول دستور Add، کلید و پارامتر دوم مقدار را دریافت می کند. در صورتی که به عنوان کلید، مقداری تکراری پاس داده شود، پیغام خطا صادر خواهد شد. برای دسترسی به یک مقدار، می توان از کلید برای دسترسی استفاده کرد، برای مثال، می خواهیم اطلاعات دانشجویی با کد 10002 را بگیریم، به صورت زیر عمل خواهیم کرد:

var student = students["10002"];

کد بالا، شئ ای از نوع student که با کد 10002 بوسیله دستور Add اضافه شده است را برای ما بر میگرداند. در صورتی که کلید 10002 در دیکشنری وجود نداشته باشد، پیغام خطا صادر خواهد شد.

دوستان می توانند به عنوان تمرین برای برای آشنایی بیشتر با مبحث Generic ها و دیکشنری ها، برنامه ای را بنویسند که اطلاعات مخاطبین را بر اساس شماره موبایل در لیستی ذخیره کند. کلید این لیست شماره تماس و مقدار آن، کلاسی است که اطلاعات نام و نام خانودگی، آدرس و شماره موبایل را مشخص می کند.

امیدوارم که این قسمت از آموزش مورد توجه شما قرار گرفته باشد، در قسمت بعدی و به عنوان بحث پایانی دوره مقدماتی آموزش زبان سی شارپ، با بحث مدیریت خطاها و Exception ها در زبان سی شارپ آشنا خواهیم شد. ITPRO باشید

نویسنده : حسین احمدی
منبع : جزیره برنامه نویسی وب سایت توسینسو
هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی است
برچسب ها
ردیف عنوان قیمت
1 دوره آموزشی .NET Framework و زبان برنامه نویسی سی شارپ - مقدمه رایگان
2 آموزش سی شارپ - قسمت اول :: معرفی و بررسی ابزارهای مورد نیاز دوره رایگان
3 آموزش زبان سی شارپ - قسمت دوم :: آشنایی با .NET Framework و ساختار آن (بخش اول) رایگان
4 آموزش زبان سی شارپ - قسمت دوم :: آشنایی با .NET Framework و ساختار آن (بخش دوم) رایگان
5 آموزش زبان سی شارپ - قسمت سوم :: آشنایی اولیه با محیط Visual Studio و نوشتن اولین برنامه رایگان
6 آموزش زبان سی شارپ - قسمت چهارم :: آشنایی با ساختار برنامه ها و کامپایلر زبان سی شارپ رایگان
7 آموزش زبان سی شارپ - قسمت پنجم :: آشنایی با دستورات کنسول و متغیرها رایگان
8 آموزش زبان سی شارپ - قسمت ششم :: نوع های داده اولیه رایگان
9 آموزش زبان سی شارپ - قسمت هفتم :: آشنایی با عملگرهای زبان سی شارپ رایگان
10 آموزش زبان سی شارپ - قسمت هشتم :: آشنایی با دستورات کنترلی و حلقه ها (بخش اول) رایگان
11 آموزش زبان سی شارپ - قسمت هشتم :: آشنایی با دستورات کنترلی و حلقه ها (بخش دوم) رایگان
12 آموزش زبان سی شارپ - قسمت هشتم :: آشنایی با دستورات کنترلی و حلقه ها (بخش سوم) رایگان
13 آموزش زبان سی شارپ - قسمت هشتم :: آشنایی با دستورات کنترلی و حلقه ها (بخش چهارم) رایگان
14 آموزش زبان سی شارپ - قسمت نهم :: آشنایی با آرایه ها و دستور foreach رایگان
15 آموزش زبان سی شارپ - قسمت دهم :: آشنایی با متدها در زبان سی شارپ (بخش اول) رایگان
16 آموزش زبان سی شارپ - قسمت دهم :: آشنایی با متدها در زبان سی شارپ (بخش دوم) رایگان
17 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت یازدهم :: مقدمه ای بر برنامه نویسی شئ گرا رایگان
18 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت دوازدهم :: آشنایی با کلاس، اشیاء و فضاهای نام رایگان
19 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت سیزدهم :: آشنایی با فیلدها و رفتارها رایگان
20 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت چهاردهم :: آشنایی با Property ها رایگان
21 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت پانزدهم :: آشنایی با سازنده ها و روش های ایجاد اشیاء رایگان
22 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت شانزدهم :: وراثت یا Inheritance رایگان
23 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت هفدهم :: آشنایی با مفهوم Polymorphism رایگان
24 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت هجدهم:: کلاس های abstract و sealed رایگان
25 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت نوزدهم :: سازنده ها در وراثت، کلمه کلیدی protected و فیلدهای readonly رایگان
26 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت بیستم :: کلاس های static و partial و Extension Method ها رایگان
27 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت بیست و یکم :: Reference Types و Value Types رایگان
28 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت بیست و دوم :: آشنایی با کاربرد interface ها رایگان
29 آموزش برنامه نویسی شئ گرا در زبان سی شارپ - قسمت بیست و سوم :: آشنایی با مفاهیم Inversion of Control و Dependency Injection رایگان
30 آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و چهارم :: آشنایی با مفهوم Type Casting و انواع Cast ها رایگان
31 آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و پنجم :: آشنایی با operator overloading و تعریف cast ها رایگان
32 آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و ششم :: مفاهیم boxing و unboxing رایگان
33 آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و هفتم :: قابلیت Generics رایگان
34 آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و هشتم :: نکات تکمیلی Generic ها، کلاس List و کلاس Dictionary رایگان
35 آموزش زبان سی شارپ -قسمت بیست و نهم (پایانی): استثناء ها (Exceptions) و مدیریت خطاها در سی شارپ رایگان
مطالب مرتبط

در حال دریافت اطلاعات

نظرات
هیچ نظری ارسال نشده است

    برای ارسال نظر ابتدا به سایت وارد شوید

    arrow