C# Generics
Introduction to C# Generics
Generics को C# language और CLR (Common Language Runtime) के version 2.0 में introduce किया गया था। यदि आपने C++ में templates के बारे में पढ़ा हुआ है तो C# के इस feature को आप आसानी से समझ और उपयोग कर पाएंगे। हालाँकि generics और templates same नहीं है लेकिन दोनों का purpose same ही है।
Generics के माध्यम से ऐसी classes, interfaces, methods, arrays और delegates define किये जा सकते है जो किसी भी type से independent होते है या फिर सभी type के data के साथ work कर सकते है।
उदाहरण के लिए निचे दिए गए method को देखिये। यह method दो integer numbers को add करता है।
public int add(int a, int b)
{
return a+b;
}
इस method के साथ problem ये है की आप इस method से float या double numbers को नहीं add कर सकते है। इससे सिर्फ integer numbers ही add किये जा सकते है। लेकिन इस method का generic version create करके आप उससे सभी types के numbers को add कर सकते है।
Generics से पहले यदि किसी code को किसी दूसरे type के लिए reuse करना होता था तो इसके लिए एक type से दूसरे type में casting करनी होती थी। यदि casting नहीं की जाती थी तो हर type के लिए same code को अलग से लिखना होता था। यह एक समस्या थी क्योंकि इससे code की size भी बढ़ जाती थी और application की performance भी कम हो जाती थी।
लेकिन जब आप एक generic code लिखते है तो ना तो आपको casting करने की आवश्यकता होती है और ना ही हर type के लिए अलग से code लिखने की आवश्यकता होती है। क्योंकि generic code सभी types के साथ work कर सकता है।
Generics के कुछ benifits निचे दिए जा रहे है।
- जैसा की आपको पता है एक generic code को किसी भी type के लिए use किया जा सकता है। इसलिए हर type के लिए अलग से code लिखने की बजाय एक ही code को बार बार reuse किया जा सकता है। इससे code reusability बढ़ती है।
- जब आप generics को use करते है तो आपको casting और boxing जैसी processing करने की आवश्यकता नहीं होती है। इससे आपकी application की performance बढ़ती है।
- Generic code को सिर्फ कुछ special types के साथ work करने के लिए भी create किया जा सकता है। ऐसे में आप आसानी से execution को control कर पाते है।
Generic Type Parameters
Generics द्वारा .NET framework में type parameters (int, float, class, delegate, event आदि types को parameters के रूप में use करना) के concept को introduce किया गया है।
जब आप कोई generic code define करते है तो generic type parameter भी define करते है। Generic type parameter के द्वारा ही उस type को accept किया जाता है जिस type के लिए आप generic code को use करना चाहते है।
Generic type parameter किसी type के लिए एक placeholder होता है। वह type user द्वारा तब define किया जाता है जब वे generic code को किसी type के लिए use करना चाहते है।
उदाहरण के लिए यदि add() method के generic version से आप float numbers को add करना चाहेंगे तो इसके लिए आप float को generic type argument की तरह pass करेंगे। इसी प्रकार यदि integer numbers को add करेंगे तो integer को generic type argument के रूप में pass किया जाएगा।
एक generic code को आप directly use नहीं कर सकते है क्योंकि असल में generic code कोई real code नहीं होता है। Generic code को use करने के लिए आपको एक type (int, float, class, interface, delegate आदि) argument के रूप में pass करना होता है।
आपके द्वारा pass किया गया type run time के दौरान generic type parameter को replace कर देता है। Generic type सिर्फ एक blue print होता है जो उसी type के अनुसार work करता है जो type उसे pass किया गया है।
Generic type parameter को angular brackets (<>) में define किया जाता है। हालाँकि आप Generic type parameters के रूप में कोई भी नाम use कर सकते है लेकिन इसके लिए निचे कुछ guidelines दी जा रही है जिन्हें आपको follow करना चाहिए।
- Generic type parameter के रूप में आप एक लम्बा नाम use कर सकते है लेकिन यदि single letter का नाम काफी हो तो आपको उसे ही use करना चाहिए।
- यदि आप एक single letter को generic type parameter के रूप में use कर रहे तो आपको T letter use करना चाहिए। T एक general naming convention जो industry में सभी द्वारा follow किया जाता है। T से programmer को समझने में भी आसानी होती है की argument के रूप में एक type pass किया जाना चाहिए।
- यदि आप कोई लम्बा नाम use करना चाहते है तो उससे पहले T को prefix कर सकते है। ऐसा करने से आसानी से समझने में सहूलियत होती है।
एक बात आपको हमेशा ध्यान रखनी चाहिए की जब आप generic type parameter को angular brackets के साथ use करते है तो वह compiler को यह बताता है की वह type या method एक generic type या method है। लेकिन उस method के अंदर यदि आप generic type का कोई field create करते है तो उसके लिए आप बिना angular brackets के ही generic type parameter को define करते है।
C# में आप classes, delegates, interfaces, events और methods को generic define कर सकते है। इनके बारे में आगे detail से बताया जा रहा है।
Generic Classes
एक generic class में ऐसे operations (methods) को define किया जा सकता है जो किसी एक type से सम्बंधित नहीं है। Generic class का प्रयोग आप linked lists, hash tables, stacks, queues, tree आदि collections (data structures) को define करने के लिए कर सकते है।
क्योंकि collections में सभी operations एक ही तरह से perform किये जाते है चाहे कोई सा भी type use किया जाए। .NET framework library में सभी collection classes के generic versions भी available है जो उनके non generic versions से अधिक use किये जाते है।
C# में generic class define करने का general syntax निचे दिया जा रहा है।
class-keyword class-name <generic-type-parameter>
{
//Define some methods and fields with <generic-type-parameter>
}
जैसा की आप ऊपर दिए गए syntax में देख सकते है एक generic class का syntax भी किसी normal class की तरह ही होता है। लेकिन generic class को define करते समय class के नाम के बाद आप generic type parameter भी define करते है।
इसके अलावा आप class के अंदर भी methods और fields define करते है उन सबके type के रूप में आप generic type parameter ही define कर सकते है। लेकिन सभी methods और fields को generic type parameter के साथ define करना आवश्यक नहीं है। साथ ही जब आप class का object create करते है तब भी class के नाम के बाद generic type parameter define करते है।
C# में generic classes का use निचे उदाहरण द्वारा समझाया जा रहा है।
using System;
class genericDemo<T>
{
T value;
public genericDemo(T v)
{
this.value = v;
}
public void display()
{
Console.WriteLine(this.value);
}
}
class genericDemoFinal
{
static void Main(string[] args)
{
genericDemo<int> gdI = new genericDemo<int>(2);
gdI.display();
genericDemo<string> gdS = new genericDemo<string>("Hello");
gdS.display();
}
}
ऊपर दिया गया उदाहरण निचे दिया गया output generate करता है।
2
Hello
Generic Delegates
C# में generic delegate declare करने का general syntax निचे दिया जा रहा है।
delegate-keyword type-paramter delegate-name <type-parameter>(type-paramter a, type-paramter b....);
Delegate के नाम के बाद generic type parameter angular brackets में define किया जाता है। लेकिन delegate का return type और parameter type define करते समय generic type parameter बिना angular brackets के define किया जाता है।
C# में generic delegates का use निचे उदाहरण द्वारा समझाया जा रहा है।
using System;
delegate void Aoperation<T>(T a, T b);
class ArithOperation
{
public void AddOperation(int a, int b)
{
Console.WriteLine("Sum is : {0}",a+b);
}
public void MulOperation(int a, int b)
{
Console.WriteLine("Product is : {0}",a*b);
}
}
class arithOperationFinal
{
static void Main(string[] args)
{
ArithOperation ao = new ArithOperation();
Aoperation<int> addO = new Aoperation<int>(ao.AddOperation);
addO(2,2);
Aoperation<int> mulO = new Aoperation<int>(ao.MulOperation);
mulO(2,3);
}
}
ऊपर दिया गया उदाहरण निचे दिया गया output generate करता है।
Sum is : 4
Product is : 6
Generic Methods
C# में generic methods define करने का general syntax निचे दिया जा रहा है।
access-modifier return-type function-name<generic-type-parameter>(ref T a, ref T b....)
{
//
}
Generic method का use निचे उदाहरण द्वारा समझाया जा रहा है।
using System;
class genericMethod
{
public void display<T>(T value)
{
Console.WriteLine(value);
}
}
class genericMethodFinal
{
static void Main(string[] args)
{
genericMethod gM = new genericMethod();
gM.display(5);
gM.display("India");
}
}
ऊपर दिया गया उदाहरण निचे दिया गया output generate करता है।
5
India
Generic Interfaces
C# में generic interfaces define करने का general syntax निचे दिया जा रहा है।
access-modifier interface-keyword interface-name<generic-type-parameter>
{
//Member that will use generic type parameter as type
//other members
}
जैसा की आप ऊपर दिए गए syntax में देख सकते है एक generic interface भी किसी normal interface की तरह ही create किया जाता है। फर्क केवल सिर्फ इतना होता है की generic interface में interface के नाम के बाद generic type parameter define किया जाता है।