• 0
bashmohandes

مقدمة في ال Generics (الجزء الثاني)

سؤال

بعد ان تم شرح المفهوم الاساسي للGenerics في الدرس السابق و أيضا تم شرح ال Generics بوجه خاص في ال VB.net ننتقل الان الى الجزء الثاني و هو ال Generic Functions

تابع معي هذا الكود

Module Module1

 Sub Main()
     Dim I As Integer = 5
     Dim J As Integer = 7
     Swap(Of Integer)(I, J)
     Console.WriteLine("I = " & I)
     Console.WriteLine("J = " & J)

     Dim S As String = "Paul"
     Dim R As String = "Lori"
     Swap(Of String)(S, R)
     Console.WriteLine("S = " & S)
     Console.WriteLine("R = " & R)

     Console.ReadLine()

 End Sub

   Public Sub Swap(Of T)(ByRef a As T, ByRef b As T)

     Dim temp As T
     temp = a
     a = b
     b = temp
   End Sub

End Module

في هذا الModule قمنا بعمل الfunction الشهيرة Swap و لكن على طريقة الGenerics اي انها تقوم بعمل الSwap للDataType المحدد لها اثناء الCall .

تابع في الMain ستجد اولا

Swap(Of Integer)(I, J)

و هنا اصبحت الFunction موجهة الى عمل Swap للمتغيرات من نوع Integer

ثم قمنا بعد ذلك بمناداة نفس الFunction و لكن هكذا

      Swap(Of String)(S, R)

فأصبحت الFunction تقوم بعمل Swap للمتغيرات من نوع String و هكذا

اعتقد ان الفكرة مفهومة و لكن هل هذا كل شئ؟

لا و لكن يمكنك ان تضع بعض الConstraints او القيود على الType الذي تقبله الFunction تابع هذا الكود

Public Sub Swap(Of T As Structure)(ByRef a As T, ByRef b As T)
 Dim temp As T
 temp = a
 a = b
 b = temp
End Sub

لاحظ كلمة Structure الموجودة و التي حددت ان يكون الDataType الذي يراد عمل الSwap للمتغيرات من نوعه هو Structure معنى هذا ان هذه الFunction لا يمكن استخدامها هكذا

      Swap(Of String)(S, R)

لان المتغيرات من نوع String لا تخضع لهذا الشرط

جميل جدا بقيت نقطة اخيرة

ماذا عن الOverloading ؟

تابع معي هذا الكود

Sub Foo
Sub Foo(ByVal s As String)
Sub Foo(Of T)( ByVal arg As T)
Sub Foo(Of T, U)(ByVal arg1 As T, ByVal arg2 as U)

ستجد ان تواجد هذه الSubs سويا في Class او Module واحد صحيح 100%

ملحوظة: مترجم عن موقع www.developer.com

Generic Function

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

7 إجابة على هذا السؤال .

  • 0

الدرس القادم

داخل الCLI ماذا يحدث عند استخدام الGenerics و ماذا عن الPerformace و الCode Sharing

؟؟؟؟؟؟؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

الدرس الاخير في ال Generics

و هو ماذا يحدث داخل ال CLI لتنفيذ الGenerics في الRun Time

عندما نفكر سويا قبل ان نرى ماذا فعلت Microsoft في أرض الواقع سنجد ان لدينا حالتين فرضتهم علينا ظروف اللغة.

الحالة الاولى

و هي الحالة التي تقوم فيها بعمل Generic من ValueType مثل List(of Integer) او List(of Double)

ففي هذه الحالة يجب ان يتم في داخل الJIT Compiler اثناء التنفيذ بناء Specialized Native Code لكل new instance بمعنى انه اذا كان هناك List من نوع Integer فيجب ان يتم عمل Generation لNative Code خاص بالInteger الذي يكون حجمه32 بت و اذا اتى بعد هذا السطر سطر اخر فيه List من الDouble فيجب ان يقوم بعمل Generation لCode جديد يناسب الDouble لأنه لا يساوي الInteger في الحجم و هكذا لا نستطيع استخدام نفس الNative Code لكل الInstances من نفس ال Generic. و هذا مايسمى Code Specialization

الحالة الثانية

و هي الحالة التي تقوم فيها بعمل Instance من Generic باستخدام Reference Type مثل Dog, Cat, BusinnessObject او اي شئ اخر و كما نعرف فان جميع الReferences لها نفس الحجم و هو 32 بت و هو حجم الPointer أذن يمكنا استغلال هذه النقطة في ان نعيد استخدام الGenerated Native Code مرة اخرى مع كل الInstances من نفس الGeneric ماداموا جميعا يطلبون Instance من Reference Type و هو مايسمى Code Sharing مما يحسن استخدام الMemory

اذن بعد هذه النظرة السريعة تعالى نرى ماقامت به Microsoft في Dot Net 2.0

كالعادة يجب ان نحاول الاستفادة من كلا الحالتين و نحاول دمجهم فببساطة كاملة عندما يتم استدعاء Generic لأول مرة سواء كانت لReference Type او Value Type فإن الJIT Compiler يقوم بعمل نسخة Native من الGeneric في الMemory.

عندما يتم استدعاء الGeneric مرة اخرى فإن الJIT Compiler يقوم بعمل Check على الType المطلوب فإذا كان Reference Type فإنه يستخدم نفس الNative Code أما اذا كان Value Type فإنه يقوم بعمل New Native Version بالType المطلوب في كل مرة

ارجو ان يكون شرحي المتواضع قد وصل الى اذهانكم المعلومة بشكل صحيح.

الموضوع بالكامل بالانجليزية للغة ال#C

http://www.c-sharpcorner.com/Code/2004/Mar...icsInCSharp.asp

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم،،

ممكن تساعدني،، واجهتني مشكلة في فهم الموضوع قليلا، هل لك أن تطبق الشفرة التالية وتنظر ما هي النتائج؟: (أعتقد أنك بحاجة إلى تحرير الشفرة قليلا)!

class Base{}
class Child1 extends Base{
public String ToString(){
return "Child1";
}
}
class Child2 extends Base{
public String toString(){
return "Child2";
}
}

public static void Main(){
Child1 c1=new Child1();
Child2 c2=new Child2();
swap(c1, c2);
Console.Write(c1);
Console.Write(c2);
}
public static <T extends Base> void swap(ref T t1, ref T t2){
T temp=t1;
t1=t2;
t2=temp;
}

يعطيك العافية!!

وإن فهمت ما أرمي إليه، فأرجو أن توضح!

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

للرفع..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مرة ثانية...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

يا أبو مازن عندما حولت الكود الى #C لم يعمل و أعطى Compile Time Error

 class Program
   {
       static void Main(string[] args)
       {
           Child1 c1 = new Child1();
           Child2 c2 = new Child2();
           Swap<Base>(ref c1, ref c2);// هنا ظهر الخطأ في الCompile
           Console.WriteLine(c1);
           Console.WriteLine(c2);
       }

       public static void Swap<T>(ref Base obj1, ref Base obj2) where T : Base
       {
           Base tmp = obj2;
           obj2 = obj1;
           obj1 = tmp;
       }
   }

   abstract class Base
   {
   }

   class Child1 : Base
   {
       public override string ToString()
       {
           return "Child1";
       }
   }

   class Child2 : Base
   {
       public override string ToString()
       {
           return "Child2";        
       }

   }

لا أعرف اذا كان هذا ما تقصده

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أليست هكذا؟

 static void Main(string[] args)
      {
          Child1 c1 = new Child1();
          Child2 c2 = new Child2();
          Swap<Base>(c1, c2);// بدون كلمة ref
          Console.WriteLine(c1);
          Console.WriteLine(c2);
      }

      public static void Swap<T>(ref T obj1, ref T obj2) where T : Base//وضع الحرف بدلا من Base
      {
          T tmp = obj2; // change Base to T
          obj2 = obj1;
          obj1 = tmp;
      }

ولماذا

Swap<Base> (c1,c2)

وليست

Swap(c1,c2);

ألا يفترض أن تكون معروفة في وقت الترجمة!؟

وما هي الأخطاء بالضبط؟! ألا يشرح المترجم أيا منها؟

تم تعديل بواسطه أبومازن
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .