Generics (X#X)

შეიძლება ვქონდეს ფუნქცია ან კლასი რომელიც ღებულობს რაღაც პარამეტრებს მაგრამ ტიპი ჯერ  განსაზღვრული არ არი (ანუ ჯერ გაურკვეველია პარამეტრის ტიპი double, string, თუ float).  ამ შემთხვევაში შეიძლება გამოსავალი იყოს objeqt – ის ტიპის პარამეტრის გამოყენება ანუ Object ტიპის  გავლით შემიძლია კლასს ან ფუნქციას მივაწოდო ნებისმიერი ტიპის პარამეტრი (ეს შესაძლებელია იმის გამო,  რომ ნებისმიერი ტიპი იქნება ეს int თუ Random წარმოადგენს ან სტრუქტურას ან კლასს, რომელიც   თავისთავად დაკავშირებულია მემკვიდრეობით, Object კლასთან( ეს ისედაც ცხადია რადგან .Net–ში  Object არის ყველა კლასის მშობელი)) მაგრამ ასეთი გამოსავალი არ არი გამართლებული, რადგან   მართალია ამ დროს ჩვენ თავისუფლად გადავცემთ სხვადასხვა ტიპის პარამეტრს მაგრამ სამაგიეროდ ვერანაირად ვაღარ გავაკონტროლებთ თუ რა ტიპის პარამეტრი გადავეცით. შედეგად დიდი ალბათობაა საჩუქრად მივიღოთ რანთაიმ ერორი. გამოსავალს წარმოადგენს ჯენერიკი რომელიც   ფუნქციისთვის ან კლასისთვის პრამეტრის გადაცემის მეთოდს წარმოადგენს, ჯენერიკი პროგრანმირების ენის  ნაწილია და განისაზღვრება გარკვეული ფუნქციის ან კლასის სინტაქსში, ჯენერიკის დახმარებით შესაძლებელია ფუნქციას ან კლასს გადავცეთ პარამეტრი ან პარამეტრები მაშინაც, როდესაც პარამეტრების ტიპი არ არის   განსაზღვრული. განვიხილოთ მაგალითის სფუძველზე  კლასს GenericList – ს გადაეცემა ორი პარამეტრი რომლის ტიპი ჯრჯერობით უცნობია პარამეტრების გადაცემა  ხდება “< >” ნიშნებს შორის, პარამეტრები აღინიშნება რაიმე სიმბოლოებით ჩვენს შემთხვევაში ეს არის T და K  ხოლო T პარამეტრის ტიპი ასევე გადაეცემა Add ფუნქციას.  როგორც მაგალითიდან ჩანს Main ფუნქციაში შეიქმნა სამი ობიექტი list1, list2 და list3 და სამივე სხვადასხვა ჯენერიკ ტიპის პარამეტრებით, ამასთან   TestGenericList – ის შიგნით ვქმნით ExampleClass კლასს და ობიქტის შექმნისას კლასს გადავცემთ ExampleClass   ტიპის პარამეტრს, ეს სავსებით დასაშვებია ჯენერიკის შემთხვევაში.

using System;
using System.Linq;
using System.Text;
// Declare the generic class
public class GenericList <T, K> {
 public void Add(T input) {
 Console.WriteLine(input);
  }
}

//
//მაგალითი მეორე
public class GenericList2<T, K>
 where T : Random, new()
 where K : T, new() {
 //where T : int, string, new(){ //where K : T, Random, new() {
 public void WriteText() {
    T tt = new T();
    K kk = new K();
 Console.WriteLine(tt.Next(100));
 Console.Write(kk.Next(300));
  }
}
public class ExampleClass { }  

class TestGenericList {

 static void Main() {
 // Declare a list of type int 
 GenericList<int, string> list1 = new GenericList<int, string>();
 // Declare a list of type string
 GenericList<string, float> list2 = new GenericList<string, float>();
   // 
 GenericList<ExampleClass, double> list3 = new GenericList<ExampleClass, double>();
 GenericList2<Random, Random> list4 = new GenericList2<Random, Random>();
   list4.WriteText();
 Console.Read();
  }
}

ასეთი შედეგი Object ტიპის გამოყენებითაც შეგვეძლო მიგვეღო,  მაგრამ მთავარი  განსხვავება ის არის რომ ჯენერიკების შემთხვევაში შეგვიძლია გავაკონტროლოთ  თუ რა და რა ტიპის  პარამეტრები შეიძლება გადაეცეს კლასს ან ფუნქციას.  განვიხილოთ მეორე მაგალითი  პირველი რასაც შევნიშნავთ GenericList2 კლასში ეს არის  where T : Random, new() და  where K : T, new() {  რითაც  პიველ შემთხვევაში T პარამეტრად მიღებული იქნება მხოლოდ Random – ის   ტიპის პარამეტრები, ხოლო K-ს პარამეტრად ის პარამეტრები რასაც მოცავს  T  ტიპი.  new() საშუალებას გვაძლევს შევქმნათ ობიექტი  უპარამეტრო კონსტრუქტორით, ჩვენს შემთხვევაში ეს საჭირო არცაა   რადგან  Random-ს გააჩნია ცარიელი კონსტრუქტორი მაგრამ, მაგრამ ჯენერიკად ისეთი  ტიპების გამოყენების   შემთხვევში რომელთა კლასსაც არა აქვს ცარიელი  კონსტრუქტორი, new() – ის დაწერა აუცილებელია.  ანუ ჯენერიკით  ყველანაირად ვაკონტროლებთ გადმოცეულ პარამეტრებს მაგალითად იმის მიხედვით თუ რომელ კლასს   ეკუთვნის, რომელი კლასის მემკვიდრეა, კალასია თუ  სტრუქტურაა რომელ კლასთან არის დაკავშირებული ინტერფეისით და ასეშემდეგ. აღსანიშნავია ისიც რომ კომპილაციისას ჯენერიკიანი ფუნქციები იქნება თუ კლასსები შეიცვლებიან განსაზღვრულ პარამეტრებიან  ფუნქციებად და კლასებად. ამდენი  სისულელის წაკითხვის შემდეგ ვისარ გაუჩნდება კითხვა თუ საერთოდ რა საჭიროა    ჯენერიკის გამოყენება. ჩვეულებრივ არც არი აუცილებელი მაგრამ თუ ვაკეთებთ რაიმე უნივერსალურ კლასს რომელსაც  არ ვიცით ვინ როდის რა დანიშნულებით გამოიყენებს მას (ანუ რა პარამეტრებს მიაწვდის) ასეთ დროს მოსახერხებელია ჯენერიკების გამოყენება.

მეორე Random პარამეტრებიან მაგალითი რამდენადმე გაურკვეველია. ჩვეულებრივ როდესაც ასეთი ტიპის ჯენერიკში ხდება მისაღები გარამეტრების ტიპის წინასწარ მითითება, გამოიყენება ინტერფეისები, ანუ where T : პირობის მერე გადაეცემა ინტერფეისის ტიპი და აქედან გამომდინარე გენერიკის ტიპად დაშვებული იქნება  ნებიმიერი კლასი რომელიც მოცემულ ინტერფეისს დააკმაყოფილებს

http://www.codeproject.com/KB/books/EssentialCS20.aspx
Generics Video
ProgrammingVideoTutorials.com
MSDN Generics (C# Programming Guide)

Advertisements
This entry was posted in C# Programming. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s