Constraint Types in C#

new() Constructor Constraint

ये Constraint हमें किसी Generic Type के Object को Instantiate करने की सुविधा देता है, जबकि सामान्‍य रूप से हम किसी Generic Type को Parameter Type के रूप में Specify करके Generic Type का Object Create नहीं कर सकते लेकिन जब हम new() Constraint को Specify करते हैं, तो जिस किसी भी Type के Instance को हम Constructor के माध्‍यम से Create करते हैं, हर उस Type को हम Generic Class के Parameter Type के रूप में Use कर सकते हैं।

new() Constructor वास्तव में Default Constructor को Represent करता है, जिसे हर Class/Structure में .NET Framework द्वारा Automatically Provide किया जाता है और new() Constraint को Specify करके हम किसी भी Type के Default Constructor को Invoke कर सकते हैं। Default Constructor को No-Argument या Parameterless Constructor भी कहा जाता है।

File Name: newConstructorInterfaceConstraint.cs
using System;

namespace CSharpGenerics
{
    class BaseClass { }
    class OtherClass { }

    class GenClass<T> where T : new()
    {
        T genObject;

        public GenClass()
        {
            genObject = new T();
        }

        public void DisplayMessage()
        {
            Console.WriteLine(genObject);
        }
    }

    class newConstructorInterfaceConstraint
    {
        static void Main()
        {
            GenClass<BaseClass> genBaseObject = new GenClass<BaseClass>();
            genBaseObject.DisplayMessage();

            GenClass<OtherClass> genOtherObject = new GenClass<OtherClass>();
            genOtherObject.DisplayMessage();
        }
    }
}

// Output:
   CSharpGenerics.BaseClass
   CSharpGenerics.OtherClass

इस Program में हमने हमारी Generic Class को निम्नानुसार तरीके से new() Constraint का प्रयोग करते हुए Design किया है:

    class GenClass<T> where T : new()
    {
        T genObject;

        public GenClass()
        {
            genObject = new T();
        }

        public void DisplayMessage()
        {
            Console.WriteLine(genObject);
        }
    }

जब हम इस प्रकार से new() Constructor को Constraint की तरह Specify करते हैं, तो उस स्थिति में हम Generic Type <T> का Object Create करने के लिए new Keyword का प्रयोग कर सकते हैं। इसीलिए इस Generic Method में निम्न Default Constructor कोई Error Generate नहीं करता:

        public GenClass()
        {
            genObject = new T();
        }

जबकि हमने इस Default Constructor में T() Constructor Type का Object Create किया है, जबकि T Type एक Generic Type है।

जब हम Generic Type का Object Create करते हैं तो Parameter Type के रूप में हम हर उस Type को Specify कर सकते हैं, जिसमें Default Constructor होता है। परिणामस्वरूप ये Generic Type उस Default Constructor वाले Specified Type के प्रकार के लिए Constructed Type Create कर सकता है।

साथ ही जब ये Constructor BaseClass को Parameter Type के रूप में Specify करने पर Execute होता है, तो BaseClass के लिए एक Generic Type Create करता है और उस Newly Created BaseClass Generic Type के Reference को genObject में Store कर देता है। परिणामस्वरूप genBaseObject के लिए DisplayMessage() Method को Execute करने पर हमें निम्नानुसार Output प्राप्त होता है:

CSharpGenerics.BaseClass

इसी तरह से जब ये Constructor OtherClass को Parameter Type के रूप में Specify करने पर Execute होता है, तो OtherClass के लिए एक Generic Type Create करता है और उस Newly Created OtherClass Generic Type के Reference को genObject में Store कर देता है। परिणामस्वरूप genOtherObject के लिए DisplayMessage() Method को Execute करने पर हमें निम्नानुसार Output प्राप्त होता है:

CSharpGenerics.OtherClass

इस प्रकार से हम new() Constructor को Use करके किसी भी Class के Constructor को Specify करते हुए Generic Class में Parameter Type के रूप में Specified Class का Generic Object Create कर सकते हैं, जो कि केवल new() Constructor के कारण ही सम्भव है।

जब हम new() Constraint को Use करते हैं, तब हमें मूल रूप से तीन मुख्‍य बातें ध्‍यान में रखनी होती हैं:

  • जब एक से ज्यादा Parameter Type को Specify करना होता है, तब new() Constraint को किसी भी अन्‍य Constraint के साथ Use किया जा सकता है। लेकिन उस स्थिति में new() Constraint को अन्तिम Constraint की तरह Specify करना जरूरी होता है।
  • new() हमें किसी Parameterless यानी Default Constructor के आधार पर Object Create करने की सुविधा देता है, फिर भले ही उस Constructor की Class में अन्‍य Constructors Defined हों या न हों। यानी हम new() Constraint को Use करने पर Generic Class में किसी Parameter को Specify नहीं कर सकते। और
  • हम किसी Value Type Constraint के साथ new() को Specify नहीं कर सकते क्योंकि new Keyword Compiler को हमेंशा Heap Area में Memory Reserve करने का Instruction देता है, जबकि Value Type Variables हमेंशा Stack में Create होते हैं।

Reference Type and Value Type Constraints

हम Generic Type के साथ Parameter Type के रूप में Reference Type अथवा Value Types को Specify कर सकते हैं। Reference Type Constraint को Specify करने के लिए हमें निम्नानुसार Syntax का प्रयोग करना होता है:

where T : class

जहां class Keyword इसी बात को Indicate कर रहा है कि हम Parameter Type के रूप में किसी Reference Type को ही Specify कर सकते हैं। यदि हम इस Syntax को Use करने के बाद Parameter Type के रूप में किसी Value Type को Use करें, तो C# Compiler Compile Time Error Generate करता है। इसी तरह से Value Type Constraint को Specify करने के लिए हमें निम्नानुसार Syntax को Use करना होता है:

where T : struct

जहां struct Keyword इसी बात को Indicate कर रहा है कि हम Parameter Type के रूप में किसी Value Type को ही Specify कर सकते हैं। यदि हम इस Syntax को Use करने के बाद Parameter Type के रूप में किसी Reference Type को Use करें, तो C# Compiler Compile Time Error Generate करता है।

File Name: ValueTypeConstraint.cs
using System;

namespace CSharpGenerics
{
    struct ValueType { }

    class GenClass<T> where T : struct
    {
        T genObject;

        public GenClass(T argObject)
        {
            genObject = argObject;
        }

        public void DisplayMessage()
        {
            Console.WriteLine("Value: " + genObject);
        }
    }

    class ValueTypeConstraint
    {
        static void Main()
        {
            GenClass<int> genValueType1 = new GenClass<int>(10);
            genValueType1.DisplayMessage();

            GenClass<ValueType> genValueType2 = new GenClass<ValueType>(new ValueType());
            genValueType2.DisplayMessage();

            //GenClass<string> genReferenceType1 = new GenClass<string>("Hello Generics.");
            //genReferenceType1.DisplayMessage();
        }
    }
}

// Output:
   Value: 10
   Value: CSharpGenerics.ValueType

इस Program में हमने int Type व User Defined Structure Type को Generic के Parameter Type के रूप में Specify किया है। हम ऐसा कर सकते हैं, क्योंकि हमारा Generic एक Value Type को Parameter के रूप में Accept कर सकता है।

लेकिन इस Program में Specified Commented Statement को यदि हम Normal Statement में Convert कर दें, तो हमें Compile Time Error प्राप्त होती है, क्योंकि string Type एक Reference Type होता है और हम अपनी GenClass नाम की Generic Class के Parameter Type के रूप में किसी Reference Type को Specify नहीं कर सकते।

File Name: ReferenceTypeConstraint.cs
using System;

namespace CSharpGenerics
{
    class ReferenceType { }

    class GenClass<T> where T : class
    {
        T genObject;

        public GenClass(T argObject)
        {
            genObject = argObject;
        }

        public void DisplayMessage()
        {
            Console.WriteLine("Value: " + genObject);
        }
    }

    class ReferenceTypeConstraint
    {
        static void Main()
        {
            //GenClass<int> genValueType1 = new GenClass<int>(10);
            //genValueType1.DisplayMessage();

            GenClass<string> refType1 = new GenClass<string>("Hello Generics.");
            refType1.DisplayMessage();

            ReferenceType x = new ReferenceType();
            GenClass<ReferenceType> refType2 = new GenClass<ReferenceType>(x);
            refType2.DisplayMessage();
        }
    }
}

// Output:
   Value: Hello Generics.
   Value: CSharpGenerics.ReferenceType

इस Program में हमने string Type व User Defined Structure Type को Generic के Parameter Type के रूप में Specify किया है। हम ऐसा कर सकते हैं, क्योंकि हमारा Generic एक Reference Type को Parameter के रूप में Accept कर सकता है।

लेकिन इस Program में Specified Commented Statement को यदि हम Normal Statement में Convert कर दें, तो हमें Compile Time Error प्राप्त होती है, क्योंकि int Type एक Value Type होता है और हम अपनी GenClass नाम की Generic Class के Parameter Type के रूप में किसी Value Type को Specify नहीं कर सकते।

Type Parameter Relationship with Constraint

हम किसी Generic Type के साथ एक से ज्यादा Parameter Type Specify कर सकते हैं और जब हम एक से ज्यादा Parameter Types को Specify करते हैं, तो Constraints का प्रयोग करते हुए उनके बीच Relationship भी Specify कर सकते हैं। जैसे:

	class GenericClass<T, V> where V : T
	{
		// . . .
	}

यदि हम इस तरह का Implementation Create करते हैं, तो where Clause Compiler को इस बात की Instruction देता है कि V को या तो T के समान Type का होना चाहिए या फिर T के Derived Type का होना चाहिए। यदि ये Generic Class के साथ Specified Types V T के बीच ये Relationship Exist न हो, तो Compiler Compile Time Error Return करता है। जब कोई Constraint उपरोक्तानुसार Parameter Type Use करता है, तो इस तरह के Constraint को Naked Type Constraint कहा जाता है।

Multiple Constraints

हम Parameter Type के रूप में एक से ज्यादा Constraint को Specify कर सकते हैं। जब हमें किसी Generic Type में एक से ज्यादा Parameter Type को Specify करना होता है, तब हमें सभी Constraints को एक Comma Separated List के रूप में Specify करना होता है।

यदि Constraint के रूप में struct, class या किसी Base Class को इस Comma Separated List में Specify किया जा रहा हो, तो इन्हें हमेंशा List की शु:आत में Specify करना जरूरी होता है। फिर हमें दूसरे Constraint के रूप में Interface Constraints को Specify करना होता है तथा यदि new() Constraint Exist हो, तो उसे हमेंशा List के अन्तिम Constraint के रूप में Specify करना होता है। यदि हम इस क्रम को Change करते हैं, तो Compiler Error Generate करता है। इस Constraint के Valid Declaration को हम निम्नानुसार Specify कर सकते हैं:

class GenericClass<T> where T : BaseClass, IInterface, new()

जब हम Multiple Constraints को Specify करते हैं, तब हर Type Parameter के लिए हम Constraint Specify कर सकते हैं और हर Constraint को Specify करने के लिए हमें Separate where Clause को Use करना होता है। लेकिन इनके बीच Whitespaces के अलावा किसी भी अन्‍य Punctuation को Use नहीं कर सकते। जैसे:

File Name: MultipleConstraints.cs
using System;

namespace CSharpGenerics
{
    class GenClass<T, V>
        where T : class
        where V : struct
    {
        T referenceObject;
        V valueObject;

        public GenClass(T argTObject, V argVObject)
        {
            referenceObject = argTObject;
            valueObject = argVObject;
        }

        public void DisplayMessage()
        {
            Console.WriteLine("Name: {0}", referenceObject);
            Console.WriteLine("Salary: {0} PA", valueObject);
        }
    }

    class UsingMultipleConstraints
    {
        static void Main()
        {
            GenClass<string, int> refType = new GenClass<string, int>("Kuldeep", 600000);
            refType.DisplayMessage();
        }
    }
}

// Output:
   Name: Kuldeep
   Salary: 600000 PA

इस Program में हमने GenClass में दो Parameter Type Define किए हैं, जिनमें से एक Parameter Type Reference Type को Accept करता है, जबकि दूसरा Parameter Type Value Type को। (Constraint Types in C#)

C# in Hindiये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

C#.NET in Hindi | Page:908 | Format: PDF

BUY NOW GET DEMO REVIEWS