محدودیت نوع (Type Constraints)

کد جنريک بايد براي هر نوع داده‌ای کار کند. يک عمل محاسباتي مانند عمل جمع که بر روي انواع صحيح انجام می‌شود، نمی‌تواند در صورتي که عملگر + سربارگذاري نشده باشد، بر روي ساير اشياء عمل کند. در نتيجه شما بايد براي يک متد يا کلاس جنريک محدوديت نوع (Type Constraints) در نظر بگيريد که فقط انواع خاصي در اين ليست محدوديت قرار بگيرند.

public class GenericClass<T> where T: int
{
    //some code
}

براي ايجاد اين محدوديت ابتدا کلمه کليدي where سپس نام نوع پارامتر، يک کالن (:) و در آخر اگر پارامتر T داراي ليستي از محدودیت‌ها است بايد آنها را به وسيله کاما از هم جدا کنيم. کد بالا داراي يک محدوديت است و آن نوع int می‌باشد، بدين معني که کلاس جنريک ما فقط می‌تواند اين نوع را قبول کند. اگر بخواهيد چندين محدوديت ايجاد کنيد بايد به صورت زير عمل نماييد :

public class GenericClass<T> where T: int, string
{
    //some code
}

پارامتر T در کد بالا فقط نوع int و string را قبول می‌کند. می‌توانید از کلمه کليدي struct استفاده کنيد بدين معني که، کلاس جنريک فقط انواع مقداري را قبول کند و يا کلمه کليدي Class را به کار بريد که کلاس جنريک فقط انواع مرجع را پذيرا باشد. همچنين می‌توان از کلمه کليدي interface هم استفاده کرد، که در نتيجه کلاس می‌تواند اشيايي که رابطها را پياده سازي می‌کنند را، قبول کند.

public class GenericClass<T> where T: struct
{
    //some code
}

public class GenericClass<T> where T: class
{
    //some code
}

public class GenericClass<T> where T: interface
{
    //some code
}

همچنين می‌توان نام يک کلاس را به عنوان محدوديت نوع تعيين کرد. بدين معني که نوع را محدود به آن کلاس و کلاس‌های مشتق شده از آن کند. می‌توان تعيين کرد که کلاس جنريک فقط کلاسهايي که داراي يک سازنده بدون پارامتر هستند را قبول کند. براي ايجاد اين محدوديت بايد از ()new به صورت زير استفاده شود :

public class GenericClass<T> where T: new()
{
    //some code
}

در اين مورد اگر چندين محدوديت وجود داشته باشد بايد ()new را در آخر آنها قرار دهيم. اگر کلاس داراي چندين پارامتر باشد و شما بخواهيد براي هر يک از آنها محدودیت‌های مختلفي ايجاد کند می‌توانید دستور where را به صورت زير اعمال نماييد :

public class GenericClass<T1, T2> where T1 : int where T2 : string
{
    //some code
}

اگر يک کلاس جنريک از يک کلاس ديگر ارث بري کند بايد نام آن کلاس را قبل از محدودیت‌ها ذکر نماييد.

public class GenericClass<T1, T2> : BaseClass where T1 : int where T2 : string
{
    //some code
}