C# & .Net Flashcards
(49 cards)
تعریف متود
static
چه فایده ای دارد؟
با استفاده از متود استاتیک در یک کلاس می توانیم بدون ایجاد یک شی از آن کلاس به این متود دسترسی پیدا کنیم.
تعریف متدهای استاتیک می تواند به الگوی
factory pattern
کمک کند و به عنوان یک کارخانه عمل کند و نمونه هایی از آن کلاس را برای ما بسازد.
چرا در
arraylist
نیاز به تبدیل نوع داده
(casting)
داریم اما در
List<>
این نیاز را نداریم؟
arraylist
مجموعه ای از اشیا است که هر نوع داده ای می تواند باشد زیرا نوع آن
object
است.
وقتی یک شی را از
arraylist
میخوانیم، آن شی به عنوان
object
بازگشت داده می شود.
برای اینکه به متودها و ویژگی های آن شی خودمان دسترسی داشته باشیم، باید این
object
را به شی خودمان تبدیل
(casting)
کنیم.
اما
List<>
مجموعه ای از اشیا با نوع داده ی مشخص است.
مثلا
List<Product>
این لیست بالا فقط اشیایی از جنس
Product
می تواند داشته باشد.</Product>
در c#
بهترین متود برای مرتب کردن آیتم ها کدام است؟
OrderBy(p=>p.Name)
برای
nullable
کردن یک متغیر در کلاس چگونه عمل می کنیم؟
در
Constructor
به شکل زیر می نویسیم:
public Product (string name, decimal? price = null)
{
this.name = name;
this.price = price;
}
انواع تایپ ها در
generic
را بگویید و مثالی از کد آن بزنید.
Open Type:
نوع پارامتر مشخص نمی شود.
Closed Type:
نوع پارامتر مشخص می شود.
این نوع بهتر است زیرا در زمان اجرا شدن کد، خطاها زودتر و دقیق تر مشخص می شوند.
کلاس جنریک
Dictionary:
Dictionary<string, int> wordCount = new Dictionary<string, int>();
wordCount[“Hello”] = 1;
wordCount[“World”] = 2;
foreach (var word in wordCount)
{
Console.WriteLine($”{word.Key}: {word.Value}”);
}
Guid
در دات نت چیست؟
Guid
Globally Unique Identifier
یک نوع داده خاص در دات نت است که برای شناسایی منحصر به فرد اشیا در سیستم ها و دیتابیس ها به کار می رود.
مانند
ID
عمل می کند.
یک
Guid
معمولاً به صورت یک رشته متنی با فرمت خاص نمایش داده میشود که شامل 32 رقم هگزادسیمال و 4 خط تیره است.
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public User (string Name) { Id = Guid.NewGuid(); this.Name = Name; }
تابع
ConvertAll()
چه نوع تابعی است و توضیح دهید.
تابع
ConvertAll()
یک تابع جنریک است.
و این امکان را می دهد که یک
List<T>
لیست از نوع
T
را به لیست دیگری از نوع
TOutput
List<TOutput>
تبدیل کنیم.
List<string> numbers = new List<string> {"1", "2", "3"};
List<int> newNumbers = numbers.ConvertAll<int>(x=> int.Parse(x));
foreach (var number in newNumbers)
{
Console.WriteLine(number);
}</int></int></string></string></TOutput></T>
تفاوت
Refrence Type
و
Value Type
را بنویسید
Refrence Type
(نوع مرجع)
به اشیا
(object)
اشاره دارد و در حافظه به صورت
refrence
ذخیره می شود.
Value Type
مستقیم به خود داده اشاره دارد.
مثل
float, int, struct
Generic Types
Refrence Type Constraint
چیست؟
محدودیت نوع مرجع یا
Refrence Type Constraint
این امکان را می دهد که فقط و فقط از مرجع
(class)
به عنوان نوع پارامتر می توان استفاده کرد و مثلا نمی توان از
float, int, struct , …
به عنوان نوع پارامتر استفاده کرد.
public class Repository<T> where T : class
{
private List<T> items = new List<T>();</T></T></T>
public void AddItem(T item) { items.Add(item); } public T GetItem(int iindex) { return items[iindex]; } }
Generic Types
Value Type Constraint
چیست؟
محدودیت نوع مقدار یا
Value Type Constraint
این امکان را می دهد که فقط از نوع مقدار باید برای نوع پارامتر استفاده کنیم.
مثل
imt, enum, …
class ValSample<T> where T : struct {
}</T>
Generic Types
Constructor Type Constraint
چیست؟
محدودیت نوع سازنده
نعیین می کند، پارامتری که می گیرد باید سازنده یا
constructor
بدون پارامتر داشته باشد.
public class Sample
{
public T CreateInstance<T>() where T : new()
{
return new T();
}
}</T>
public class ExampleClass
{
public string Name { get; set; }
public ExampleClass () { Name = "Default Name"; } } Sample sample = new Sample(); ExampleClass instance = sample.CreateInstance<ExampleClass>(); Console.WriteLine(instance.Name);
Generic Types
Conversion Type Constraint
چیست؟
محدودیت نوع تبدیل
این امکان را می دهد که
نوع پارامتر انتخابی باید از یک اینترفیس یا یک کلاس مشخص پیروی کند.
public class Comparer<T> where T : IComparable<T>
{
public bool IsGreaterThan(T first, T second)
{
return first.CompareTo(second) > 0;
}
}
int num1 = new int();
int num2 = new int();
num1 = 10;
num2 = 6;
var comparer = new Comparer<int>();</int></T></T>
Generic Types
Type Inference in Generic Methods
Type Inference
این امکان را می دهد که در متد جنریک، نوع آرگومان را به طور مستقیم مشخص نکنیم.
بلکه با توجه به آرگومانی که به متد جنریک می دهیم، خود کامپایلر متوجه می شود این متد از چه نوعی است.
static List<T> MakeList<T>(T first, T second)
List<string> list = MakeList<string>("Line 1", "Line 2");
در آبجکت بالا دیگر نیازی نیست به متد
MakeList
نوع آرگومان
string
را پاس دهیم بلکه مثال پایین می گوید چزور کامپایلر تشخیص می دهد که آرگومان از نوع
string
است.
List<string> list = MakeList("Line1", "Line2");</string></string></string></T></T>
اگر نوع پارامتر بدون محدودیت یعنی
unconstrained
باشد
چگونه می توان آن را مقایسه کرد؟
۱. مقایسه با
== و !=
در نوعهای بدون محدودیت
فقط برای
. null
فقط با
== و !=
می توان آن پارامتر را با
null
مقایسه کرد و نمی توان دو پارامتر از نوع
T
را با
== و !=
مقایسه کرد. چون هیچ تضمینی نیست که این دو پارامتر از نوع یکسان باشند.
reference comparison
مقایسه ی مرجع یا
reference comparison
دو مقدار را با هم مقایسه می کند که آیا هر دو به یک شی یا یک مرجع اشاره می کنند یا خیر.
string str1 = “Hello”;
string str2 = “Hello”;
Console.WriteLine(str1 == str2);
خروجی مقایسه بالا
false
می شود زیرا
مقدار داخل هر دو
“hello”
اما
str1 و str2
دو شیء مستقل هستند،
یعنی به دو آدرس مختلف در حافظه اشاره دارند.
کلاس جنریک
Tuple (T1, T2)
این کلاس دو مقدار از انواع مختلف را ذخیره کند
مثلا
Tuple(string, int)
Tuple(int, string) pair = new Tuple(int, string)(10, “value”);
arraylist
و
List
را از لحاظ جنریک بودن یا نبودن چگونه مقایسه می کنید؟
ArrayList
یک مجموعه غیر جنریک است یعنی مجموعه ای از اشیا
(object)
است که نیاز به
boxing و unboxing
یعنی تبدیل نوع داده،
داریم.
List
یک مجموعه جنریک است که نیاز به
boxing و unboxing
نداریم.
Generics
typeof(genericMethod)
این متد
typeof()
یک ورودی جنریک متود می گیرد که نوع جنریک و نوع پارامتر آن جنریک را مشخص می کند.
public class ReflectionExample
{
public static void ShowTypeInfo<x>()
{
Type GenericDefinition = typeof(Dictionary<,>);
Console.WriteLine($"Dictionary<,>: {GenericDefinition}");</x>
Type constructedtype = typeof(List<x>); Console.WriteLine($"List<x>: {constructedtype}"); Type closedtype = typeof(Dictionary<int,string>); Console.WriteLine($"Dictionary<int,string>: {closedtype}"); } } که x بالا می تواند هر نوع داده ای باشد مثل int, string, list , ...
GetGenericTypeDefinition()
این متود یک ورودی جنریک متود را می گیرد و فقط نوع جنریک متود را مشخص می کند.
GetGenericTypeDefinition(List<int>)
ورودی زیر را می دهد:
System.Collections.Generic.List`1[T]</int>
مثال دیگر:
Type constructedtype = typeof(List<int>);
Type getgenericdefinitiontype = constructedtype.GetGenericTypeDefinition();
Console.WriteLine(getgenericdefinitiontype);
ورودی زیر را می دهد:
System.Collections.Generic.List`1[T]
Console.WriteLine(typeof(List<int>));
ورودی زیر را می دهد:
System.Collections.Generic.List`1[System.Int32]
Console.WriteLine(constructedtype == getgenericdefinitiontype);
ورودی زیر را می دهد:
false</int></int>
MakeGenericType()
یک قالب جنریک اصلی داریم که می خواهیم نوع پارامترهای آن ها را مشخص کنیم و یک متود جنریک
closed type
بسازیم.
Type dictionary = typeof(Dictionary<,>); –قالب جنریک اصلی
Type cosntructedtype = dictionary.MakeGenericType(typeof(string), typeof(int)); –مشخص کردن نوع پارامترهای جنریک
Console.WriteLine(cosntructedtype);
هم پوشانی در آرایه ها چه معایبی دارد که لیست ها از هم پوشانی پشتیبانی نمی کنند؟
class Animal { }
class Cat : Animal { }
class Turtle : Animal { }
Animal[] animals = new Cat[5];
در کد بالا چون
Cat
زیرکلاسی از
Animal
است،
آرایه ای از
Animal
به آرایه ای از
Cat
اشاره می کند.
اما به این آرایه ی
animals
نمی توان یک زیرکلاس دیگری که از یک نوع دیگری باشد، اضافه کرد، چون این آرایه فقط از آبجکت های
Cat
باید باشد.
مثلا کد پایین خطا می دهد:
animals[0] = new Turtle();
به همین دلیل جنریک ها در زبان سی شارپ از هم پوشانی پشتیبانی نمی کنند تا مانع بروز این خطا شوند.
مانند لیست در کد زیر:
List<Animal> animals = new List<Animal>();</Animal></Animal>
// اضافه کردن آبجکتهای Cat به لیست Animal animals.Add(new Cat()); animals.Add(new Cat()); // دسترسی به اعضای لیست foreach (Animal animal in animals) { animal.Speak(); // خروجی: Meow! }
Nullable<T></T>
دراین نوع جنریک، پارامتر
T
از نوع
value type
است و نمی تواند برای نوع دیگری از پارامتر به کار رود.
در واقع این متد جنریک، یک
value Type
را به نوعی تبدیل می کند که می تواند نال باشد.
Hasvalue –>
چک می کند که متغیر مقدار دارد یا خیر
Nullable<DateTime> date = null; --> یک تاریخ نال پذیر بدون مقدار اولیه</DateTime>
if (!date.HasValue)
{
Console.WriteLine(“The date doesnt set yet.”);
}
date = DateTime.Now;
if (date.HasValue)
{
Console.WriteLine($”now date: {date}”);
}
کاربرد
GetValueOrDefault()
برای متغیراز جنس
Nullable<T></T>
این متد یا خود
value
را برمی گرداند یا مقدار دیفالتی که به متد می دهیم را بر می گرداند.
static void Display(Nullable<int> x)
{
Console.WriteLine("HasValue: {0}", x.HasValue);
if (x.HasValue)
{
Console.WriteLine("Value: {0}", x.Value);
Console.WriteLine("Explicit conversion: {0}", x);
}
Console.WriteLine($"GetValueOrDefault: {x.GetValueOrDefault()}");
Console.WriteLine($"GetValueOrDefault: {x.GetValueOrDefault(10)}");</int>
}
static void Main(string[] args)
{
Nullable<int> x = new Nullable<int>(); Console.WriteLine("Instance without value:"); Display(x);
boxing VS unboxing
boxing:
تبدیل مقدار ارزش به آبجکت
int? nullable = 5;
object boxednullable = nullable;
unboxing:
عکس عمل باکسینگ
یعنی تبدیل آبجکت به مقدار ارزش
int normal = int(boxednullable );