منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب

نسخة كاملة : التحويل بين أنواع البيانات باستخدام التضييق Explicit والتوسيع Implicit
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
كاتب الموضوع : samerselo


لنفرض أنه لدينا برنامج من النوع كونسول مسمى TypeConversions كما هو ظاهر في الكود التالي


كود :
Module Program

Sub Main()
Console.WriteLine("***** The Amazing Addition Program *****")
Dim a As Short = 9
Dim b As Short = 10
Console.WriteLine("a + b = {0}", Add(a, b))
End Sub

Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
Return x + y
End Function

End Module
لاحظ أن الطريقة Add تتوقع أن يمرر لها محددين من النوع Integer ومع ذلك نلاحظ أن الإجراء Main يمرر لها في الواقع محددين من النوع Short وقد يبدو هذا عدم تطابق كلي في أنواع البيانات إلا أن البرنامج يتم تنفيذه وترجمته بدون أخطاء ويعيد القيمة 19 كما هو متوقع. ويعود السبب في ذلك إلى أنه لا يوجد احتمال لحدوث فقدان في البيانات بما أن القيمة الأعظمية للنوع Short هي 32767 بينما تكون للنوع Integer هو 217483647 فيقوم المترجم آليا بتوسيع كل قيمة من النوع Short إلى النوع Integer وذلك بعملية نسخ تلقائية من Short إلى Integer. وبالرغم من أن عملية التعريض الآلية قد تمت لصالحنا في المثال السابق ولكن في بعض الحالات قد تتسبب في أخطاء زمن التنفيذ يصعب كشفها.
افترض أنك قمت بتعديل قيم المتغيران في المثال السابق بحيث عندما يتم جمعهما معا يتسببان في حدوث فيضان على القيمة الأعظمية للنوع Short وبافتراض أنك تقوم بتخزين القيمة المعادة من الطريقة Add ضمن متغير محلي من النوع Short إضافة إلى إظهار النتيجة على الكونسول


كود :
Module Program

Sub Main()
Console.WriteLine("***** The Amazing Addition Program *****")
Dim a As Short = 30000
Dim b As Short = 30000
Dim answer As Short = Add(a, b)
Console.WriteLine("a + b = {0}", answer)
End Sub

Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
Return x + y
End Function

End Module
فعلى الرغم من أن البرنامج تتم ترجمته بصورة صحيحة هنا إلا أنه عندما يتم تنفيذ البرنامج فسوف يتم إطلاق خطأ زمن التنفيذ System.OverflowException وبالرغم من أن الطريقة Add يمكنها إعادة Integer يحمل القيمة الصحيحة التي تقع ضمن مجال قيم النوع Integer ولكن لا يمكن تخزين تلك القيمة في متغير من النوع Short لأن القيمة تقع خارج مجال القيم التي يمكن تخزينها ضمن النوع Short ففي هذه الحالة يحاول المترجم القيام بعملية تضييق التي ستنتج خطأ فيضان في زمن التنفيذ. ولكن ليست جميع عمليات التضييق ينتج عنها الخطأ System.OverflowwException انظر للمثال التالي


كود :
Dim myByte As Byte
Dim myInt As Integer = 200
myByte = myInt
Console.WriteLine("Value of myByte: {0}", myByte)
ففي الكود السابق تكون القيمة المحتواة في المتغير Integer تقع ضمن مجال النوع Byte لذا فتحويل التضييق لا يتسبب في إطلاق خطأ زمن التنفيذ ومع أن العديد من تحويلات التضييق تعتبر آمنة فإنه من الأفضل تعقب تحويلات التضييق عند الترجمة قبل أن نصل إلى زمن التنفيذ ويتم ذلك باستخدام توجيه المترجم Option Strict

فهم Option Strict

يتأكد Option Strict في زمن الترجمة عوضا عن زمن التنفيذ من تحويلات التضييق ويعطينا إعلاما بحيث يمكننا تصحيحه في وقت مبكر فعندما نستطيع تحديد تحويلات التضييق هذه يمكننا اتخاذ إجراءات تصحيحية وتخفيف خطر ظهور أخطاء في زمن التنفيذ. ومع أنه يمكنك تحديد هذا الخيار في بداية كل ملف كود


كود :
Option Strict On
إلا أنه يمكننا أيضا تفعيل التوجيه Option Strict أو إيقافه للمشروع ككل وذلك بتحديد الخيار المناسب من صفحة Compile من خصائص MyProject فعندما تقوم بتفعيل هذا الخيار فأنت تعلم المترجم بأن عليه التحقق من هذه الاحتمالات خلال عملية الترجمة وسوف يولد لك خطأ في زمن الترجمة عن كل عملية تحويل تضييق.
ويمكننا إضافة الخيار Option Strict لمثالنا السابق ليقوم المترجم بالتحقق من عمليات التضييق حيث يمكننا تغيير نوع المتغير الذي سيحمل النتيجة من النوع Short إلى النوع Integer الذي يمكنه حمل النتيجة بأمان


كود :
Dim answer As Integer = Add(a, b)
دالات التحويل المحدد

يزودنا فيجول بايزيك بعدد من دالات التحويل التي تمكننا من التحويل بين الأنواع بأمان مثل CBool و CByte و CDate و CDbl و CInt إضافة إلى الوظيفة CType التي تأخذ محددين الأول هو البيانات التي لديك والثاني هو نوع البيانات المراد فمثلا سطري الكود التاليين يعتبران متكافئين


كود :
myByte = CByte(myInt)
myByte = CType(myInt, Byte)
وتكمن الفائدة في الوظيفة CType هي أنها تستطيع التعامل مع جميع عمليات التحويل بين مختلف الأنواع والفئات الأساسية والمشتقة وكذلك الأغراض وواجهاتها

دور System.Convert

من أجل إكمال الحديث عن موضوع التحويل يحب علينا إلقاء نظرة على مجال الأسماء System الذي يحتوي على الفئة Convert التي يمكن استخدامها أيضا في عمليات تحويل التضييق والتعريض كما في المثال


كود :
myByte = Convert.ToByte(myInt)
وتكمن الفائدة من استخدام الفئة System.Convert في أنها توفر طريقة لغوية طبيعية للتحويل بين مختلف أنواع البيانات ومع ذلك يزودنا فيجول بايزيك 2008 بكم جيد من وظائف التحويل المضمنة مثل CBool و CByte حيث أن استخدام الفئة Convert للقيام بعمليات التحويل لا يعدو كونه خيار تفضيل شخصي