منذ ولادة لغة Visual Basic في عام 1991، أصبحت أداة عالية الكفاءة لبناء التطبيقات. وبعد ما يقرب من 20 عامًا، يستمر في توفير التكامل السهل مع Microsoft .NET Framework، مما يمكّن المطورين من كتابة التطبيقات التي تشمل أجهزة الكمبيوتر المكتبية والهواتف والمتصفحات وحتى السحابية.
ستقوم Microsoft بإصدار Visual Studio 2010 هذا الشهر، والذي يتضمن الإصدار 10 من Visual Basic (يسمى أحيانًا VB 2010 أو VB10). يعد هذا الإصدار هو الأقوى حتى الآن ويتضمن العديد من الميزات الموفرة للوقت لمساعدة المطورين على القيام بالمزيد باستخدام عدد أقل من أسطر التعليمات البرمجية. هنا، سيتم تزويدك بكل المحتوى اللازم لفهم Visual Basic والاستفادة منه بشكل كامل في Visual Studio 2010.
التطور المشترك
في الماضي، تم تطوير Visual Basic وC# بواسطة فرق منفصلة، مما أدى غالبًا إلى ظهور الميزات أولاً في إحدى اللغات ثم في اللغة الأخرى. على سبيل المثال، يحتوي C# على خصائص تم تنفيذها تلقائيًا ومهيئات مجموعة غير متوفرة في Visual Basic، ويحتوي Visual Basic على ميزات مثل الربط المتأخر والمعلمات الاختيارية غير المتوفرة في C#. ولكن في كل مرة تحصل فيها لغة ما على ميزة جديدة، يطلب العديد من العملاء إضافة هذه الميزة إلى اللغة الأخرى أيضًا.
لتلبية هذه الحاجة، قامت Microsoft بدمج فريقي Visual Basic وC# لتنفيذ استراتيجية التطور المشترك. والغرض من ذلك هو تعزيز التنمية المشتركة لهذه اللغات. عندما يتم تقديم ميزة رئيسية في إحدى اللغات، فإنها تظهر في اللغة الأخرى أيضًا. هذا لا يعني أن كل ميزة ستكون موجودة في كلتا اللغتين وستعمل بنفس الطريقة تمامًا؛ في الواقع، كل لغة لها تاريخها وروحها وإحساسها - ومن المهم الحفاظ على هذه الخصائص.
في .NET Framework 4، اتخذ Visual Basic وC# خطوة كبيرة نحو هذا الهدف، حيث استوعب كل منهما العديد من الميزات الموجودة لدى الآخر. ومع ذلك، فإن التطور المشترك لا يؤثر فقط على الوظائف السابقة، بل هو أيضًا استراتيجية للتطوير المستقبلي لهذه اللغات. وبهذه الروح، يقدم .NET Framework 4 ميزات جديدة قوية في كلتا اللغتين، مثل وقت تشغيل اللغة الديناميكي، وأنواع التشغيل المتداخل المضمنة، والتباين العام، مما يسمح لمطوري Visual Basic وC# بالاستفادة الكاملة من .NET Framework.
ما الجديد في فيجوال بيسك 2010
تم تصميم الميزات الجديدة في Visual Basic 2010 لمساعدتك على إنجاز المزيد باستخدام عدد أقل من أسطر التعليمات البرمجية. قام فريق تصميم Visual Basic الخاص بنا بإلقاء نظرة فاحصة على الأماكن التي يتعين على المطورين عادةً كتابة الكثير من التعليمات البرمجية النمطية المملة، ووجدوا طرقًا للسماح للمترجم بالقيام بالعمل بدلاً من ذلك. بالطبع، هذه نظرة شاملة، والآن دعونا نلقي نظرة أعمق على كل ميزة.
حرف استمرار السطر الضمني
Visual Basic هي لغة موجهة نحو الأسطر وتستخدم بناء جملة واضحًا مشابهًا للغة الإنجليزية لتحسين إمكانية القراءة. ولكن هذا يؤدي غالبًا إلى وصول التعليمات البرمجية إلى حد 80 حرفًا لكل سطر، مما يجبر المطورين على القيام بالكثير من التمرير. يمكنك استخدام الشرطة السفلية لإخبار المترجم بأن معالجة السطر التالي يجب أن تستمر كالسطر الحالي (أي التعامل مع خطوط فعلية متعددة كخط منطقي واحد). لكن الاضطرار إلى كتابة حرف الشرطة السفلية بشكل متكرر كان أمرًا مزعجًا، وفي الواقع كان أحد أهم طلبات الميزات لسنوات هو مطالبة المترجم بإصلاح هذه المشكلة.
في Visual Basic 2010، يمكن للمترجم حل هذه المشكلة. يعرف المترجم الآن الرموز المميزة (مثل الفواصل والأقواس وعوامل التشغيل) التي تميل إلى الظهور قبل أحرف متابعة السطر، ويقوم بإدراج الأحرف حتى لا يحتاج المطورون إلى إدراج أحرف. على سبيل المثال، من المؤكد أنه ليس من المنطقي إنهاء عبارة Visual Basic بفاصلة؛ يعرف المترجم ذلك، لذلك عندما يرى المترجم دفقًا من الرموز المميزة مثل {comma, enter}، فإنه يستنتج وجود حرف استمرار السطر، كما هو مبين في الشكل يظهر المثال في 1.
الشكل 1: استنتج أحرف استمرار السطر
<Extension()>
دالة التصفية حسب البلد(
عملاء ByVal كـ IEnumerable(من العملاء)،
بلد ByVal كسلسلة) كـ IEnumerable (من العملاء)
استعلام خافت =
من ج في العملاء
حيث ج.البلد = البلد
حدد <العميل>
<%=
ج.الاسم &
، &
ج.البلد
%>
</العميل>
الاستعلام عن العودة
وظيفة النهاية
في Visual Basic 2008، يتطلب الكود الموجود في الشكل 1 9 أحرف سفلية. ومع ذلك، في كل حالة من الحالات التالية، يستنتج المترجم متى تكون الشرطة السفلية ضرورية ويسمح بتجاهلها:
بعد السمة <Extension()>
بعد ((القوس الأيسر) في إعلان الطريقة
بعد (الفاصلة) للمعلمة الأولى
قبل) (قوس أيمن) في إعلان الطريقة
بعد = (علامة المساواة)
بعد <%= (العلامة الافتتاحية للتعبير المضمن)
بعد كل علامة عطف (علامة الضم) في نص XML
قبل %> (علامة النهاية للتعبير المضمن)
تعد ميزة المترجم الجديدة هذه مفيدة بشكل خاص لتوقيعات الطريقة، والتي ستعمل أيضًا بشكل جيد لأكثر من 80 حرفًا في المثال الموضح (إذا كان كل جزء على نفس السطر). في الشكل 2، سترى جميع مجموعات العلامات والمواضع التي تكون أحرف استمرار السطر ضمنية فيها.
الشكل 2 عندما يكون حرف استمرار السطر ضمنيًا
علامة | قبل | بعد |
، (فاصلة)، . (فترة)، > (السمة)، ( { (القوس الأيسر)، <%= (علامة بدء التعبير المضمنة (نص XML)) | X | |
)، }، ] (القوس الأيمن)، %> (علامة نهاية التعبير المضمنة) | X | |
جميع الكلمات الرئيسية لـ LINQ: تجميع، تمييز، من، تجميع حسب، الانضمام إلى المجموعة، الانضمام، السماح، الترتيب حسب، تحديد، تخطي، تخطي أثناء، أخذ، أخذ بينما، أين، في، إلى، تشغيل، تصاعدي، تنازلي | X | X |
المشغل: +, -,*,/,/,^,>>,<<,Mod,&,+=,-=,*=,/=,/=,^=,>>=,<<=, & =، <، <=، >، >=، <>، هل، ليس، مثل، و، أو، Xor، وأيضًا، OrElse | X | |
مع (في مُهيئ الكائن) | X |
كما ترون، هناك أكثر من 60 مكانًا في اللغة لا يلزم فيها استخدام الشرطة السفلية. (في الواقع، لا يتطلب أي من أمثلة التعليمات البرمجية الموجودة في هذه المقالة أحرف متابعة السطر.) بالطبع، لا يزال بإمكانك استخدام حرف الشرطة السفلية، لذلك سيتم تجميع التعليمات البرمجية من الإصدارات السابقة من Visual Basic كما هو متوقع.
بيانلامدا
قد يبدو مصطلح لامدا مخيفًا في البداية، لكن لامدا هي مجرد وظيفة محددة ضمن وظيفة أخرى. قدم Visual Basic 2008 تعبيرات لامدا باستخدام الكلمة الأساسية Function:
Dim customers As Customer() = ...
Array.FindAll(customers, Function(c) c.Country = Canada)
تمكّنك تعبيرات Lambda من التعبير عن المنطق محليًا بطريقة دقيقة ومدمجة دون الحاجة إلى تقسيمه عبر طرق متعددة. على سبيل المثال، إليك تمثيل التعليمات البرمجية السابقة في Visual Basic 2005 (الذي لا يدعم تعبيرات لامدا):
Dim query = Array.FindAll(customers, AddressOf Filter)
...
عامل تصفية الوظيفة (ByVal c كعميل) كقيمة منطقية
العودة ج. الدولة = كندا
وظيفة النهاية
لسوء الحظ، تتطلب تعبيرات لامدا في Visual Basic 2008 أن يقوم التعبير بإرجاع قيمة، لذلك الكود التالي:
Array.ForEach(customers, Function(c) Console.WriteLine(c.Country))
سيؤدي إلى الحالة التالية:
'Compile error: Expression does not produce a value.
Console.WriteLine هو إجراء فرعي (باطل في C#)، لذا فهو لا يُرجع قيمة، ولهذا السبب يقوم المترجم بإنشاء خطأ. للتعامل مع هذا الموقف، قدم Visual Basic 2010 دعمًا لبيانات lambdas، وهي عبارة عن lambdas تحتوي على عبارة واحدة أو أكثر:
Array.ForEach(customers, Sub(c) Console.WriteLine(c.Country))
نظرًا لأن Console.WriteLine لا يُرجع قيمة، فيمكننا فقط إنشاء دالة lambda فرعية بدلاً من دالة lambda. إليك مثال آخر باستخدام عبارات متعددة:
Array.ForEach(customers, Sub(c)
Console.WriteLine(اسم البلد:)
Console.WriteLine(c.Country)
النهاية الفرعية)
عند تشغيل هذا الرمز، فإنه يطبع سطرين لكل عميل. لاحظ أيضًا أنه إذا قمت بالتمرير فوق c أثناء البرمجة، فسترى أن المترجم سوف يستنتج النوع كعميل (من القانوني أيضًا كتابة c كعميل للإعلان عن النوع بشكل صريح). تُعد كتابة معالجات الأحداث ديناميكيًا استخدامًا رائعًا آخر لبيانات lambdas:
AddHandler b.Click, Sub(sender As Object, e As EventArgs)
MsgBox(الزر الذي تم النقر عليه)
"أدخل منطقًا أكثر تعقيدًا هنا."
نهاية الفرعية
وفي الواقع، يمكنك استخدام عبارة lambdas مع الميزة المقدمة في Visual Basic 2008: التفويض الفضفاض. (يمكنك استخدام المفوضين - مؤشرات دالة آمنة للنوع - لتنفيذ وظائف متعددة في وقت واحد.) ينتج عن هذا المزيج توقيع أبسط بكثير:
AddHandler b.Click, Sub()
MsgBox(الزر الذي تم النقر عليه)
"أدخل منطقًا أكثر تعقيدًا هنا."
نهاية الفرعية
يسمح لك رخاوة التفويض بتجاهل المعلمات تمامًا في معالجات الأحداث - وهذه ميزة رائعة، طالما لم يتم استخدامها على الإطلاق، لذا فهي متطفلة بصريًا فقط.
بالإضافة إلى لامدا الفرعية ذات السطر الواحد ولامدا الفرعية متعددة الأسطر التي رأيناها حتى الآن، يدعم Visual Basic 2010 أيضًا لامدا الوظيفية متعددة الأسطر:
Dim query = customers.Where(Function(c)
'إرجاع العملاء الذين لم يتم حفظهم فقط
"أدخل منطقًا أكثر تعقيدًا هنا."
إرجاع c.ID = -1
وظيفة النهاية)
جانب آخر مثير للاهتمام في بيانات lambdas هو كيفية تقاطعها مع المندوبين المجهولين الذين تم تقديمهم في Visual Basic 2008. غالبًا ما يخلط الناس بين هؤلاء المندوبين والأساليب المجهولة في لغة #C، على الرغم من أنها ليست متطابقة تمامًا. يحدث التفويض المجهول عندما يستنتج مترجم Visual Basic نوع المفوض بناءً على توقيع أسلوب lambda:
Dim method = Function(product As String)
إذا كان المنتج = ورق ثم
إرجاع 4.5 وحدة في المخزون
آخر
إرجاع 10'10 من كل شيء آخر
نهاية إذا
وظيفة النهاية
MsgBox(الطريقة(الورق))
إذا قمت بتشغيل هذا الرمز، فسوف ترى القيمة 4.5 معروضة في مربع الرسالة. بالإضافة إلى ذلك، إذا قمت بالتمرير فوق الأسلوب، فسترى النص Dim أسلوب As <Function(String) As Double>. نظرًا لأننا لم نوفر نوع المفوض الفعلي، فسيقوم المترجم تلقائيًا بإنشاء نوع كما يلي:
Delegate Function $compilerGeneratedName$(product As String) As Double
يُسمى هذا بالتفويض المجهول لأنه سيظهر فقط في التعليمات البرمجية التي أنشأها المترجم، وليس في التعليمات البرمجية كما هو مكتوب. لاحظ أنه في الواقع لا يتم توفير عبارة As لتحديد نوع الإرجاع الخاص بـ lambda، ويستنتج المترجم نوع الإرجاع إلى Double. سينظر المترجم إلى جميع عبارات الإرجاع داخل lambda وسيحدد النوعين Double (4.5) وInteger (10):
'Notice the As Single
طريقة خافتة = الوظيفة (المنتج كسلسلة) كمفردة
إذا كان المنتج = ورق ثم
إرجاع 4.5 وحدة في المخزون
آخر
إرجاع 10'10 من كل شيء آخر
نهاية إذا
وظيفة النهاية
ثم يقوم بعد ذلك بتشغيل خوارزمية النوع الأساسي الخاصة به ويحدد أنه يمكنه تحويل 10 إلى عدد مزدوج بأمان، ولكن لا يمكنه تحويل 4.5 إلى عدد صحيح بشكل آمن، وبالتالي فإن الخيار المزدوج هو الخيار الأفضل.
يمكنك أيضًا التحكم في نوع الإرجاع بشكل صريح، وفي هذه الحالة لن يحاول المترجم استنتاج النوع. من الشائع جدًا تعيين lambda لمتغير بنوع مفوض صريح، بدلاً من الاعتماد على المترجم لاستنتاج نوع المفوض:
Dim method As Func(Of String, Single) =
الوظيفة (المنتج)
إذا كان المنتج = ورق ثم
إرجاع 4.5 وحدة في المخزون
آخر
إرجاع 10'10 من كل شيء آخر
نهاية إذا
وظيفة النهاية
نظرًا لتوفير نوع هدف واضح، ليست هناك حاجة للإعلان كسلسلة أو كمفرد؛ يمكن للمترجم استنتاج وجوده بناءً على نوع المفوض على الجانب الأيسر من العبارة. لذا، إذا قمت بالتمرير فوق المنتج، فسترى أن النوع المستنتج هو سلسلة. لم يعد يتعين عليك تحديد "مفرد" لأن نوع المفوض يوفر هذه المعلومات بالفعل. في المثال السابق، يبدو توقيع مفوض Func (المضمن في .NET Framework) كما يلي:
Delegate Function Func(Of T, R)(ByVal param As T) As R
هناك استثناء صغير واحد، كما سنرى لاحقًا في القسم الخاص بالتباين العام.
الخصائص التي يتم تنفيذها تلقائيًا
في Visual Basic، الخصائص هي أعضاء الفئة التي تعرض حالة الكائن للعالم الخارجي. يبدو إعلان الملكية النموذجي كما يلي:
Private _Country As String
بلد الملكية كسلسلة
يحصل
Return_Country
نهاية الحصول على
تعيين (قيمة ByVal كسلسلة)
_البلد = القيمة
نهاية المجموعة
نهاية الملكية
في الواقع مفهوم بسيط جدًا يتكون من 10 أسطر من التعليمات البرمجية. نظرًا لأن الكائن النموذجي غالبًا ما يحتوي على العشرات من الخصائص، فسينتهي بك الأمر بتضمين الكثير من التعليمات البرمجية المعيارية في تعريف فئتك. لتبسيط مثل هذه المهام، يقدم Visual Basic 2010 خصائص يتم تنفيذها تلقائيًا، والتي تتيح لك تحديد خصائص بسيطة باستخدام سطر واحد فقط من التعليمات البرمجية:
Property Country As String
في هذه الحالة، سيستمر المترجم في العمل وسيقوم تلقائيًا بإنشاء الحروف والمحددات والحقول الداعمة. اسم الحقل المدعوم هو دائمًا اسم السمة مسبوقًا بحرف سفلي: _البلد في هذا المثال. يضمن اصطلاح التسمية هذا توافق التسلسل الثنائي عند تغيير الخصائص التي يتم تنفيذها تلقائيًا إلى خصائص عادية. سيستمر التسلسل الثنائي في العمل طالما أن أسماء الحقول الداعمة هي نفسها.
أحد الأشياء الرائعة التي يمكنك القيام بها باستخدام الخصائص التي يتم تنفيذها تلقائيًا هو تحديد مُهيئ يقوم بتعيين القيمة الافتراضية للخاصية عند تشغيل المُنشئ. على سبيل المثال، يقوم السيناريو الشائع مع فئات الكيانات بتعيين المفتاح الأساسي إلى قيمة مثل -1 للإشارة إلى أنه في حالة غير محفوظة. سيبدو الكود كالتالي:
Property ID As Integer = -1
عند تشغيل المُنشئ، يتم تعيين حقل الدعم (_ID) تلقائيًا على القيمة -1. تعمل صيغة المُهيئ أيضًا مع الأنواع المرجعية:
Property OrderList As List(Of Order) = New List(Of Order)
نظرًا لأنه ليس من الضروري كتابة اسم النوع مرتين، فقد لا يحتوي السطر السابق من التعليمات البرمجية على خصائص Visual Basic واضحة جدًا. والخبر السار هو أن هناك بناء جملة أقصر لإعلانات المتغيرات العادية يتوافق مع بناء الجملة الذي يسمح به Visual Basic:
Property OrderList As New List(Of Order)
يمكنك أيضًا استخدام بناء الجملة هذا مع مُهيئ الكائن للسماح بتعيين خصائص أخرى:
Property OrderList As New List(Of Order) With {.Capacity = 100}
من الواضح أنه بالنسبة للخصائص الأكثر تعقيدًا، لا يزال من الضروري استخدام بناء جملة موسع. لا يزال بإمكانك كتابة Property{Tab} لتنشيط جزء الخاصية القديم. بدلاً من ذلك، بعد كتابة السطر الأول من الخاصية، يمكنك فقط إدخال Get{Enter} وسيقوم IDE بإنشاء خاصية النمط القديم:
Property Name As String
يحصل
نهاية الحصول على
تعيين (قيمة ByVal كسلسلة)
نهاية المجموعة
نهاية الملكية
عادةً ما يجد المرء أن بناء جملة الخاصية الجديد مطابق تقريبًا لصيغة الحقول العامة، فلماذا لا نستخدم الحقول العامة بدلاً من ذلك؟ هناك عدة أسباب:
تعمل معظم البنية الأساسية لربط بيانات .NET من حيث الخصائص بدلاً من الحقول.
لا يمكن للواجهة فرض وجود حقل، بل يمكنها فرض وجود سمة.
توفر الخصائص مرونة طويلة المدى لتغيير قواعد العمل. على سبيل المثال، لنفترض أن شخصًا ما قدم قاعدة مفادها أن أرقام الهواتف يجب أن تتكون من 10 أرقام. لا يمكن إجراء هذا التحقق من الصحة إذا تم تعيينه إلى حقل عام. يعد تغيير الحقول العامة إلى خصائص تغييرًا جذريًا لسيناريوهات مثل التسلسل الثنائي والانعكاس.
مُهيئ المجموعة
من الممارسات الشائعة في .NET إنشاء مجموعة ثم ملؤها عن طريق استدعاء التابع Add مرة واحدة لكل عنصر:
Dim digits As New List(Of Integer)
أرقام.إضافة(0)
أرقام.إضافة(1)
أرقام.إضافة(2)
أرقام.إضافة(3)
أرقام.إضافة(4)
أرقام.إضافة(5)
أرقام.إضافة(6)
أرقام.إضافة(7)
أرقام.إضافة(8)
أرقام.إضافة(9)
ولكن بالنسبة لمفهوم بسيط بشكل أساسي، هناك الكثير من النفقات النحوية. قدم Visual Basic 2010 أدوات تهيئة المجموعة لتسهيل إنشاء المجموعات. لهذا الرمز:
Dim digits = New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
سيقوم المترجم تلقائيًا بإنشاء كافة الاستدعاءات إلى أسلوب الإضافة. يمكنك أيضًا استخدام وظيفة بناء الجملة الخاصة بـ Visual Basic كـ New:
Dim digits As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
لاحظ أنه في فريق Visual Basic نوصي دائمًا باستخدام بناء الجملة الثاني (كجديد) على الأول لأنه يجعل التعليمات البرمجية أكثر مرونة للتغييرات في إعداد Option Infer.
يمكنك استخدام مُهيئ المجموعة ضد أي نوع يلبي المتطلبات التالية:
يمكنك التكرار على النوع باستخدام عبارة For Each - أي أن النوع يطبق IEnumerable. (للحصول على تعريف أكثر دقة/تفصيلاً لأنواع المجموعات، راجع القسم 10.9.3 من مواصفات لغة Visual Basic على msdn.microsoft.com/library/aa711986(VS.71).aspx).
يحتوي النوع على مُنشئ بدون معلمات يمكن الوصول إليه (ولكن ليس بالضرورة عامًا).
يحتوي النوع على مثيل أو طريقة ملحق يمكن الوصول إليها (ولكن ليست عامة بالضرورة) تسمى Add.
هذا يعني أنه يمكنك أيضًا استخدام مُهيئات المجموعة لأنواع أكثر تعقيدًا، مثل القواميس:
Dim lookupTable As New Dictionary(Of Integer, String) From
{{1، واحد}،
{2، اثنان}،
{3، ثلاثة}،
{4، أربعة}}
(لاحظ أنه على الرغم من أن هذه العبارة تمتد لخمسة أسطر، إلا أنه لا توجد أحرف سفلية.) في هذه الحالة، سيقوم المترجم بإنشاء كود مكافئ للطريقة القديمة لتهيئة القاموس:
Dim lookupTable As New Dictionary(Of Integer, String)
lookupTable.Add(1, One)
lookupTable.Add(2, اثنان)
lookupTable.Add(3, ثلاثة)
lookupTable.Add(4, أربعة)
يقوم المترجم باستدعاء الأسلوب Add بمعلمتين بدلاً من واحدة. إنه يعرف كيفية القيام بذلك لأن القيمة التي تم تمريرها إلى مُهيئ المجموعة موجودة داخل أقواس متداخلة، مثل هذا: {{1, One}, {2, Two}, ...}. لكل مجموعة من الأقواس المتداخلة، يحاول المترجم تمرير هذه المعلمات إلى أسلوب Add متوافق.
من الممكن أيضًا توفير تطبيق الإضافة المخصص الخاص بك باستخدام طرق الامتداد:
<Extension()>
إضافة فرعية (مصدر ByVal كـ Ilist (من العملاء)،
معرف ByVal كعدد صحيح،
اسم ByVal كسلسلة،
مدينة ByVal كسلسلة)
source.Add(عميل جديد مع
{
.ID = معرف،
.الاسم = الاسم،
.المدينة = المدينة
})
نهاية الفرعية
(انظر إلى جميع الأحرف السفلية المفقودة!) تعمل هذه الطريقة على توسيع أي نوع يطبق IList(Of Customer)، والذي يسمح لك بعد ذلك باستخدام بناء جملة مُهيئ المجموعة الجديد، مثل هذا:
Dim list = New List(Of Customer) From
{
{1، جون، ريدموند}،
{2، بوب، سياتل}،
{3، سالي، تورونتو}
}
(أضف ثلاثة عملاء إلى القائمة). يمكنك أيضًا استخدام مُهيئات المجموعة مع الخصائص التي يتم تنفيذها تلقائيًا:
Property States As New List(Of String) From {AL, AK, AR, AZ, ...}
مصفوفة حرفية
بالإضافة إلى طرق أكثر فعالية للعمل مع أنواع المجموعات، يوفر Visual Basic 2010 أيضًا بعض التحسينات القوية للعمل مع المصفوفات. افترض الكود التالي (يعمل بشكل جيد في الإصدارات الأقدم):
Dim numbers As Integer() = New Integer() {1, 2, 3, 4, 5}
من خلال النظر إلى العناصر الموجودة في هذه المصفوفة، فمن الواضح أن كل عنصر عبارة عن عدد صحيح، لذا فإن الاضطرار إلى طباعة العدد الصحيح مرتين في هذا السطر لا يضيف أي قيمة حقًا. تسمح لك المصفوفات الحرفية بإنشاء مصفوفة عن طريق وضع جميع عناصر المصفوفة داخل أقواس متعرجة والسماح للمترجم باستنتاج الأنواع تلقائيًا:
Dim numbers = {1, 2, 3, 4, 5}
نوع الأرقام ليس كائنًا بل Integer() (طالما تم تمكين خيار Infer)، والسبب هو أن المصفوفة الحرفية تمثل نفسها الآن ولها نوعها الخاص. لنفترض مثالًا أكثر تعقيدًا:
Dim numbers = {1, 2, 3, 4, 5.555}
في هذه الحالة، سيتم استنتاج نوع الأرقام كـ Double(). يحدد المترجم النوع عن طريق فحص كل عنصر في المصفوفة وحساب النوع الأساسي، باستخدام نفس الخوارزمية التي تمت مناقشتها سابقًا لاستنتاج نوع الإرجاع لبيان لامدا. ماذا يحدث إذا لم يكن هناك نوع أساسي؟ على سبيل المثال، كما هو موضح في الكود التالي:
Dim numbers = {1, 2, 3, 4, 5}
في هذه الحالة، سيؤدي تحويل عدد صحيح إلى سلسلة إلى تقليل نطاق التحويل (أي قد يحدث فقدان البيانات في وقت التشغيل)، وبالمثل، فإن تحويل سلسلة إلى عدد صحيح سيؤدي أيضًا إلى تقليل نطاق التحويل. النوع الآمن الوحيد للاختيار من بينها هو Object() (سيقوم المترجم بإنشاء خطأ إذا تم تمكين Option Strict).
يمكن تداخل المصفوفات الحرفية لتكوين مصفوفات متعددة الأبعاد أو مصفوفات خشنة:
'2-dimensional array
مصفوفة خافتة = {{1، 0}، {0، 1}}
'مصفوفة خشنة - تفرض الأقواس تقييم المصفوفة الداخلية أولاً
خافت خشن = { ({1، 0})، ({0، 1}) }
وقت تشغيل اللغة الديناميكي
على الرغم من أن Visual Basic هي لغة ثابتة بطبيعتها من الناحية الفنية، إلا أنها تتمتع دائمًا بميزات ديناميكية قوية جدًا، مثل الربط المتأخر. يأتي Visual Studio 2010 مزودًا بمنصة جديدة تسمى Dynamic Language Runtime (DLR) التي تسهل إنشاء لغات ديناميكية - والتواصل فيما بينها. تم تحديث Visual Basic 2010 لدعم DLR بشكل كامل في مجلداته المتأخرة، مما يسمح للمطورين باستخدام المكتبات والأطر المطورة بلغات أخرى (مثل IronPython/IronRuby).
أحد الأشياء الرائعة في هذه الميزة هو أنه لم يتغير شيء من الناحية النحوية (في الواقع، لم يتم تعديل سطر واحد من التعليمات البرمجية في المترجم لدعم هذه الميزة). لا يزال بإمكان المطورين تنفيذ عمليات الربط المتأخرة كما فعلوا في الإصدارات السابقة من Visual Basic. ما تغير هو التعليمات البرمجية الموجودة في وقت تشغيل Visual Basic (Microsoft.VisualBasic.dll)، والتي تتعرف الآن على واجهة IDynamicMetaObjectProvider التي يوفرها DLR. إذا قام كائن بتنفيذ هذه الواجهة، فإن وقت تشغيل Visual Basic ينشئ DLR CallSite ويسمح للكائن واللغة التي توفره بإدخال دلالات خاصة بهم في العملية.
على سبيل المثال، تحتوي مكتبة Python القياسية على ملف يسمى Random.py، والذي يحتوي على طريقة تسمى shuffle والتي يمكن استخدامها لإعادة ترتيب العناصر في المصفوفة بشكل عشوائي. استدعاء هذه الطريقة بسيط:
Dim python As ScriptRuntime = Python.CreateRuntime()
خافت عشوائي ككائن = python.UseFile(random.py)
العناصر المعتمة = {1، 2، 3، 4، 5، 6، 7}
عشوائي.خلط(العناصر)
في وقت التشغيل، يرى Visual Basic أن الكائن يطبق IDynamicMetaObjectProvider وبالتالي يمرر التحكم إلى DLR، الذي يتصل بعد ذلك مع Python وينفذ الطريقة (تمرير المصفوفة المحددة في Visual Basic كمعلمة إلى الطريقة).
يعد هذا مثالاً على استدعاء واجهة برمجة تطبيقات ممكّنة لـ DLR، ولكن يمكن للمطورين أيضًا إنشاء واجهات برمجة التطبيقات الخاصة بهم التي تستخدم هذه الوظيفة. المفتاح هو تنفيذ واجهة IDynamicMetaObjectProvider، وفي هذه الحالة سوف يتعرف مترجمو Visual Basic وC# على الكائنات ذات دلالات ديناميكية خاصة. يرجى عدم تنفيذ هذه الواجهة يدويًا، فمن الأسهل أن ترث من فئة System.Dynamic.DynamicObject (التي تنفذ هذه الواجهة بالفعل) وتجاوز بعض الطرق فقط. يوضح الشكل 3 مثالاً كاملاً لإنشاء كائن ديناميكي مخصص (حقيبة خصائص تظهر لإنشاء خصائص بسرعة) واستخدام الربط المتأخر العادي لـ Visual Basic لاستدعاء الكائن. (لمزيد من المعلومات حول استخدام DynamicObject، اقرأ مقالة Doug Rothaus الممتازة على blogs.msdn.com/vbteam/archive/2010/01/20/fun-with-dynamic-objects-doug-rothaus.aspx .)
الشكل 3 قم بإنشاء كائن ديناميكي مخصص واستدعاء الكائن باستخدام الربط المتأخر لـ Visual Basic
Imports System.Dynamic
الوحدة النمطية1
فرعي رئيسي()
Dim p As Object = New PropertyBag
ص.واحد = 1
ص.اثنان = 2
ص.ثلاثة = 3
Console.WriteLine(ص.واحد)
Console.WriteLine(الصفحة الثانية)
Console.WriteLine(الصفحة الثالثة)
نهاية الفرعية
فئة PropertyBag: يرث DynamicObject
القيم الخاصة كقاموس جديد (من سلسلة، عدد صحيح)
وظيفة التجاوزات العامة TrySetMember(
ByVal Binder باسم SetMemberBinder،
قيمة ByVal ككائن) كقيمة منطقية
القيم (binder.Name) = القيمة
العودة صحيح
وظيفة النهاية
وظيفة التجاوزات العامة TryGetMember(
ByVal Binder باسم GetMemberBinder،
نتيجة ByRef ككائن) كقيمة منطقية
إرجاع القيم.TryGetValue(binder.Name، النتيجة)
وظيفة النهاية
نهاية الفصل
وحدة النهاية
التباين العام
هذه دالة قد تبدو معقدة بالفعل في البداية (مع مصطلحات مثل التباين المشترك والتباين)، ولكنها في الواقع بسيطة جدًا. إذا كان لديك كائن من النوع IEnumerable(Of Apple) وتريد تعيينه إلى IEnumerable(Of Fruit)، فيجب أن يكون هذا قانونيًا لأن كل تفاحة هي فاكهة (يتم فرضها عن طريق الميراث). لسوء الحظ، قبل Visual Basic 2010، لم يكن التباين العام مدعومًا في المحول البرمجي، على الرغم من أنه كان مدعومًا بالفعل في وقت تشغيل اللغة العامة (CLR).
دعونا نلقي نظرة على المثال في الشكل 4. في Visual Basic 2008، سوف ينتج عن التعليمات البرمجية الموجودة في الشكل 4 خطأ في الترجمة على السطر Dim EnableOnly (أو، إذا تم تعطيل Option Strict، فسيحدث استثناء في وقت التشغيل). الحل البديل هو استدعاء أسلوب ملحق .Cast كما يلي:
'Old way, the call to Cast(Of Control) is no longer necessary in VB 2010
Dim EnableOnly = FilterEnabledOnly(buttons.Cast(Of Control))
لم يعد هذا ضروريًا لأنه في Visual Basic 2010، تم وضع علامة على الواجهة IEnumerable كمتغير باستخدام معدل الخروج:
Interface IEnumerable(Of Out T)
...
واجهة النهاية
الشكل 4: مثال على التباين العام
Option Strict On
نموذج الصف العام 1
Sub Form1_Load() يعالج MyBase.Load
أزرار خافتة كقائمة جديدة (من الزر) من
{
زر جديد مع
{
.الاسم = بتنوك،
.ممكّن = صحيح
},
زر جديد مع
{
.الاسم = btnCancel،
.ممكّن = خطأ
}
}
خافت EnableOnly = FilterEnabledOnly (أزرار)
نهاية الفرعية
تمكين عامل التصفية فقط(
عناصر تحكم ByVal كـ IEnumerable(من التحكم)
) كـ IEnumerable(من التحكم)
العودة من ج في الضوابط
حيث c.Enabled = صحيح
وظيفة النهاية
نهاية الفصل
هذا يعني أن المعلمة العامة T أصبحت الآن متغيرًا (أي أنها مناسبة للميراث)، وسيتأكد المترجم من استخدام المعلمة فقط عندما يأتي النوع من الواجهة. يمكن أن تكون المعلمات العامة أيضًا متغيرات عكسية، مما يعني أنها تستخدم فقط حيث يتم إدخالها. يمكن أن يحتوي النوع في الواقع على كليهما. على سبيل المثال، يحتوي مندوب Func الذي تمت مناقشته سابقًا على معلمات متعارضة (لما يتم تمريره) ومعلمات مشتركة (لنوع الإرجاع):
Delegate Function Func(Of In T, Out R)(ByVal param As T) As R
يمكنك استخدام معدّلات الدخول والخروج على الواجهات والمفوضين المخصصين. تم وضع علامة على العديد من الواجهات والمفوضين الشائعين في .NET Framework 4 كمتغيرات؛ وتشمل الأمثلة الشائعة جميع مفوضي الإجراء/الوظيفة، وIEnumerable(Of T)، وIComparer(Of T)، وIQueryable(Of T)، وما إلى ذلك.
إن الشيء العظيم في التباين العام هو أنه ميزة لا داعي للقلق بشأنها على الإطلاق - إذا كان يقوم بعمله، فلن تلاحظه أبدًا. المواقف التي أدت في السابق إلى حدوث أخطاء في برنامج التحويل البرمجي أو تطلبت الاتصال بـ .Cast(Of T) تعمل بشكل جيد في Visual Basic 2010.
تحسين المعلمات الاختيارية
توفر المعلمات الاختيارية ميزة كفاءة مفيدة تسمح للمطورين ببناء أساليب أكثر مرونة وتجنب ازدحام الفصل مع العديد من التحميل الزائد للطرق. في الماضي، كان هناك قيود طفيفة مفادها أن المعلمات الاختيارية لا يمكن أن تكون فارغة (أو حتى من أي نوع بنية غير داخلية). يتيح لك Visual Basic 2010 الآن تحديد المعلمات الاختيارية لأي نوع قيمة:
Sub DisplayOrder(ByVal customer As Customer,
ByVal orderID كعدد صحيح،
وحدات ByVal الاختيارية كعدد صحيح = 0،
لون الخلفية الاختياري ByVal كاللون = لا شيء)
نهاية الفرعية
في هذا المثال، الوحدات من النوع Nullable(Of Integer) وbackgroundColor هو نوع بنية غير محتوى، ولكن لا يزال يتم استخدامها كمعلمات اختيارية. يوفر Visual Basic 2010 أيضًا دعمًا أفضل للمعلمات الاختيارية العامة.
أنواع التشغيل المتداخل المضمنة
تتمثل إحدى نقاط الضعف الشائعة في التطبيقات التي تقوم بإجراء التشغيل المتداخل لـ COM في الحاجة إلى استخدام مجموعة التشغيل المتداخل الأساسية (PIA). PIA عبارة عن تجميع .NET يعمل كملف قابل للاستدعاء في وقت التشغيل (RCW) على مكون COM ويحتوي على GUID فريد يحدده. يتصل تجميع .NET مع PIA، الذي يقوم بعد ذلك بإجراء أي تنظيم ضروري لنقل البيانات بين COM و.NET.
لسوء الحظ، يمكن أن تؤدي تطبيقات PIA إلى تعقيد عملية النشر لأنها عبارة عن مكتبات DLL إضافية يلزم نشرها على أجهزة كمبيوتر المستخدم النهائي. ويمكن أن تتسبب أيضًا في حدوث مشكلات في الإصدار - على سبيل المثال، إذا كنت تريد أن يعمل التطبيق الخاص بك مع كل من Excel 2003 وExcel 2007، فستحتاج إلى نشر كلا PIAs مع التطبيق الخاص بك.
يتم تضمين ميزة نوع التشغيل المتداخل المضمنة مباشرة في التطبيق، ولكن فقط الأنواع والأعضاء من PIA الضرورية للغاية، لذلك ليست هناك حاجة لنشر PIA على كمبيوتر المستخدم النهائي.
لتمكين هذه الميزة لكائن موجود (يتم تمكينها افتراضيًا للمراجع الجديدة)، حدد المرجع في Solution Explorer وقم بتغيير خيار Embed Interop Types في نافذة الخصائص (انظر الشكل 5). وبدلاً من ذلك، في حالة الترجمة باستخدام مترجم سطر الأوامر ming، استخدم رمز التبديل /l (أو /link) بدلاً من /r و/reference.
الشكل 5: تمكين أنواع التشغيل المتداخل المضمنة في Solution Explorer
بعد تمكين هذه الميزة، لن يعتمد التطبيق بعد الآن على PIA. في الواقع، إذا قمت بفتح التجميع في Reflector أو ildasm، ستلاحظ أنه لا يوجد في الواقع أي إشارة إلى PIA على الإطلاق.
أهداف متعددة
أفضل جزء في جميع الميزات الموجودة في Visual Basic 2010 هو أنه يمكنك استخدامها حتى في المشاريع التي تستهدف .NET Framework 2.0 من خلال .NET Framework 3.5. وهذا يعني أن ميزات مثل أحرف متابعة السطر الضمنية، والقيم الحرفية للصفيف، ومهيئات المجموعة، وبيانات lambdas، والخصائص التي يتم تنفيذها تلقائيًا، وما إلى ذلك، ستكون جميعها متاحة في المشروعات الحالية دون الحاجة إلى إعادة استهداف .NET Framework 4.
الاستثناء هو أنواع التشغيل المتداخل المضمنة، والتي تعتمد على الأنواع المتوفرة فقط في .NET Framework 4؛ لذلك، إذا كنت تستهدف إصدارات .NET Framework من 2.0 إلى 3.5، فلن تتمكن من استخدام هذه الميزة. بالإضافة إلى ذلك، يتم وضع علامة على الأنواع التي تم وضع علامة عليها كمتغيرات فقط كما كانت في .NET Framework 4، لذلك في المثال السابق، إذا كنت تستهدف الإصدارات 2.0 إلى 3.5، فلا يزال يتعين عليك الاتصال بـ .Cast(Of T). ومع ذلك، إذا كنت تستهدف هذه الإصدارات السابقة، فيمكنك إنشاء أنواع المتغيرات الخاصة بك (باستخدام معدلات الإدخال/الإخراج).
لتغيير الإطار المستهدف الحالي لتطبيقك، انقر نقرًا مزدوجًا فوق My Projects، ثم انقر فوق علامة التبويب Compile، ثم انقر فوق Advanced Compilation Options، ثم حدد من مربع التحرير والسرد الموجود بالأسفل.
لا يوجد في الواقع مفتاح سطر أوامر ming لتمكين هذه الميزة عند الترجمة من سطر أوامر ming. في الواقع، ينظر المترجم إلى التجميع الذي يوفر تعريف System.Object (عادةً mscorlib) والإطار الذي يستهدفه التجميع، ثم يضع علامة على تلك القيمة في تجميع الإخراج. (يستخدم المترجم هذه الآلية نفسها عند إنشاء تجميعات Silverlight.) عند استخدام IDE، يحدث كل هذا بشفافية، لذلك لا داعي للقلق عادةً.
مرحبا بكم في المحاولة
كما ترون، يحتوي Visual Basic 2010 على العديد من الميزات القوية التي تتيح لك أن تكون أكثر إنتاجية أثناء كتابة عدد أقل من أسطر التعليمات البرمجية والسماح للمترجم بالقيام بالمزيد من العمل. في هذه المقالة، ناقشت ميزات اللغة فقط، ولكن هناك عدد لا يحصى من التحسينات الرائعة على Visual Basic 2010 IDE. بعض التحسينات مذكورة أدناه:
انتقل إلى
تسليط الضوء على الاقتباسات
الناتجة عن الاستخدام
تحسس ذكي أفضل (مطابقة السلسلة الفرعية، البحث عن الجمل، أنماط الاقتراحات - مفيدة لاختبار أسلوب التطوير الخاص بك أولاً)
دعم شاشات متعددة
تكبير
يتطلع فريق Visual Basic إلى سماع تعليقاتك حول جهودنا لتحسين Visual Basic، لذا يرجى إرسال تعليقاتك وأسئلتك إلينا على Microsoft Connect. لمعرفة المزيد حول ميزات اللغة وIDE، راجع المحتوى الموجود على msdn.com/vbasic، والذي يتضمن مقالات وأمثلة ومقاطع فيديو إرشادية. بالطبع، أفضل طريقة للتعلم هي التعمق في المنتج واستخدامه، لذا فقد حان الوقت لتثبيته وتجربته.