السلام عليكم
فلنتابع:
عدة تغييرات طرأت على لغة الفيجوال بيسك في اصدارتها الجديدة.. التغييرات تزيد من قوة اللغة بدون اخلال لسهولتها او سهولة تعلمها <== لهذا نحبها جميعاً
Operator Overloading
لأول مرة تظهر هذه الميزة و التي افتقدها في الفيجوال بيسك..
يمكننا دائما عمل عمليات جمع و طرح و ضرب و غيرها باستخدام المعاملات operators مثل + - * / على الانواع الرقمية مثل الInteger float double و غيرها
هذه الميزة غير مدعومة لباقي الانواع الا في حالات محدودة مثل الكود التالي:
Dim inputString as String = "Hello, " Dim outputString As String = inputString + " World!"
الان يمكنك استخدام الoperators في باقي الانواع مادامت ممكنة
مثال:: يمكنك اضافة size object الى point object كما في الكود التالي::
Dim p1 As New Point(100, 100) Dim s1 As New Size(20, 30) Dim p2 As Point = p1 + s1 Dim p3 As Point = p1 – s1
اما عن النسخ السابقة من الفيجوال بيسك فكان يمكنك حل المشكلة باستخدام دوال مثل op_addition و op_subtraction و غيرها
مثال::
Dim p2 As point = Point.op_Addition(p1, s1)
في الحقيقة ان استخدام المعاملات هو استدعاء ضمني لهذه الدوال..
بالاضافة إلى ما سبق يمكن للمطورين عمل classes تستخدم هذه الخاصية
الoperators التي يمكنك اعادة استخدامها (overloading)هي::
+ + (unary) - - (unary) * \ / ^ & Like Mode And Or Xor Not << >> = (comparison) <> < <= > >= CType IsTrue IsFalse
Generics
لنفهم الGenerics يجب ان نراجع السيناريو التالي::
فلنقل ان لديك class من نوع و ليكن customer::
Class Customer Public Name As String Public Age As Integer Public Sub New(ByVal Name As String, ByVal Age As String) Me.Name = Name Me.Age = Age End Sub End Class
و الان تريد عمل collection من الcustomers، في النسخ السابقة من الفيجوال بيسك يمكنك استخدام System.Collections.ArrayList كما بالكود التالي::
Dim customerList As New System.Collections.ArrayList
customerList.Add(New Customer("Tom", 48))
customerList.Add(New Customer("Peter", 45))
customerList.Add(New Customer("Jerry", 73))
customerList.Add("Hello, this won't work!")
For Each cust As Customer In customerList
Console.WriteLine(cust.Name)
Nextانتبه اننا اضفنا 3 customers و object من نوع string!! و لن يتسبب الكود بخطأ..
ذلك لأن الArrayList يقبل بتخزين أي object بغض النظر عن نوعه.. هذه مشكلة لأنها قد تتسبب في أخطاء قاتلة اذا قمت باضافة object من نوع مختلف عن طريق الخطأ ثم عاملته بعد ذلك على انه customer.
حل المشكلة في النسخ السابقة من الفيجوال بيسك انك تعمل collection class خاص بك يرث الcollectionbase و لا يقبل اضافة اي عنصر من نوع غير الcustomer كما في المثال التالي:
Class CustomerList Inherits CollectionBase Public Sub Add(ByVal cust As Customer) Me.List.Add(cust) End Sub End Class
هذا الحل ممتاز و لكنك ستحتاج الى عمل collection مثل هذه لكل نوع لديك في المشروع مثل الorders و الproducts و غيرها مما سيتسبب في زيادة الكود و زيادة صعوبة عملية الصيانة.
الGenerics هي الحل حيث تسمح للclasses و الstructs و الinterfaces و الmethods باستقبال نوع الclass التي ستستخدمه في الكود..
الدوت نت يأتي بمجموعة من الGenerics التي غالباً لن تحتاج لغيرها (بالاضافة الى امكانية عمل Generics خاصة بك):
مثال:: يمكنك عمل List لا تقبل سوى الcustomer ::
Dim customerList As New List(Of Customer)
هل انتبهت الى كلمة Of .. هذه الكلمة هي المسئولة عن تحديد نوع الList .
و استخدام الList بالشكل التالي:
Dim customerList As New List(Of Customer)
customerList.Add(New Customer("Tom", 48))
customerList.Add(New Customer("Ken", 47))
customerList.Add(New Customer("Peter", 45))
customerList.Add(New Customer("Jerry", 73))
For Each cust As Customer In customerList
Console.WriteLine(cust.Name)
Nextاما الكود التالي لن يعمل الا اذا ازلت السطر الثالث لأنه من نوع string وليس من نوع customer
Dim customerList As New List(Of Customer)
customerList.Add(New Customer("Tom", 48))
customerList.Add("Hello there!")
Dim c As Customer = customerList(0)الGenerics في الدوت نت الجديدة ستجدها في System.Collections.Generic namespace .
امثلة:: List, Dictionary, SortedDictionary, Queue, and Stack classes و غيرها.
و كما ذكرنا من قبل يمكنك عمل Generics خاصة بك ايضاً.
Using
العديد من .Net classes تقدم طريقة Dispose .. هذه الطريقة تستخدم لاخلاء الresources المستخدمة من قبل الunmanged objects و هي كائنات لا يتمكن الgarbage collection من ازالتها تلقائياً عند انتهاء استخدامها و بالتالي تظل في الذاكرة حتى تستدعي Dispose
في العموم، يفضل ان تستخدم الDispose عندما تننتهي من استخدام اي كائن يدعم هذه الخاصية
الكود التالي يكتب كلمة Hello, World باستخدام كائني Font و Brush و في النهاية يستدعي الDispose الخاصة بهما..
Private Sub Form1_Paint( _
ByVal sender As Object, ByVal e As PaintEventArgs) _
Handles MyBase.Paint
Dim myFont As Font
Dim myBrush As Brush
Try
myFont = New Font("Verdana", 12)
myBrush = New SolidBrush(Color.FromArgb(123, 0, 123))
e.Graphics.DrawString( _
"Hello, World!", myFont, myBrush, 0, 0)
Finally
If myFont IsNot Nothing Then
myFont.Dispose()
End If
If myBrush IsNot Nothing Then
myBrush.Dispose()
End If
End Try
End Subباستخدام using يمكنك عمل block من الكود حيث يتم استدعاء الdispose تلقائياً في نهايته
مثال:
Private Sub Form1_Paint( _
ByVal sender As Object, ByVal e As PaintEventArgs) _
Handles MyBase.Paint
' Create a new font.
Using myFont As New Font("Verdana", 12)
' Create a new solid brush.
Using myBrush As New SolidBrush( _
Color.FromArgb(123, 0, 123))
e.Graphics.DrawString( _
"Hello, World!", myFont, myBrush, 0, 0)
End Using
End Using
End SubPartial Classes
تعني تقسيم الclass الى عدة ملفات يتم في النهاية دمجها في class واحد عند عملية الcompile
فوائدها:
1) فصل الكود المولد تلقائياً عن الكود الذي تكتبه (ستجده في 2003 معنون ب "Windows Form Designer generated code") مما يسهل عملية الصيانة (اعتقد ان هذه الخاصية موجهة اساساً لمبرمجي الفيجوال بيسك 6 الذين لم يعتادوا على رؤية التفاصيل في كودهم)
2) المساعدة في مشاريع التطوير الجماعية لclass واحد .. حيث يمكن لكل عضو العمل في ملفه فقط بدون مشاكل في عملية الsource control و التي يقدمها على سبيل المثال Visual Source Safe
مثال:
يتم تعريف الclass الرئيسي بالطريقة العادية:
Public Class Form1 Inherits Windows.Forms.Form ' Your Code End Class
اما الpartial class يتم باستخدام الصيغة التالية:
Partial Class Form1 ' Designer code Sub InitializeComponent() ' Your controls End Sub End Class
Background Worker Object
هي component جديدة مفيدة تماماً لكل من يريد استخدام multi threading بدون صداع و لا وجع دماغ.
الmulti-threading هو عندما تريد تنفيذ وظيفتين او اكثر في نفس الوقت بدون ان تتعطل اي وظيفة في انتظار انتهاء الوظائف الاخرى.
الخطوات:
1) اضف الcomponent الى الفورم
2) استدعي RunWorkerAsync method من الthread الرئيسي و سيتم تلقائياً عمل thread جديد ينفذ التعليمات الموجودة في حدث DoWork و ذلك دون ايقاف الشاشة الرئيسية للبرنامج او تعطيل اوامرها.
3) عند انتهاء الاوامر الموجودة في حدث DoWork سيتم اعلامك من خلال حدث RunWorkerComplete و الموجود في الthread الرئيسي أيضاً.
انتهينا..

