كيف تعمل معلمات VB.NET الاختيارية "تحت الغطاء"؟هل هي متوافقة مع CLS؟

StackOverflow https://stackoverflow.com/questions/104068

  •  01-07-2019
  •  | 
  •  

سؤال

لنفترض أن لدينا إعلان الطريقة التالي:

Public Function MyMethod(ByVal param1 As Integer, _
    Optional ByVal param2 As Integer = 0, _
    Optional ByVal param3 As Integer = 1) As Integer

    Return param1 + param2 + param3
End Function

كيف يعمل VB.NET على جعل المعلمات الاختيارية تعمل ضمن حدود CLR؟هل المعلمات الاختيارية متوافقة مع CLS؟

هل كانت مفيدة؟

المحلول

ومن المثير للاهتمام أن هذا هو كود C# الذي تم فك ترجمته، والذي تم الحصول عليه عبر العاكس.

public int MyMethod(int param1, 
                   [Optional, DefaultParameterValue(0)] int param2, 
                   [Optional, DefaultParameterValue(1)] int param3)
{
    return ((param1 + param2) + param3);
}

لاحظ السمات الاختيارية و DefaultParameterValue.حاول وضعها في أساليب C#.ستجد أنه لا يزال يتعين عليك تمرير القيم إلى الطريقة.ومع ذلك، في كود VB، تم تحويله إلى افتراضي!ومع ذلك، أنا شخصياً لم أستخدم الافتراضي مطلقًا حتى في كود VB.يبدو الأمر وكأنه اختراق.طريقة التحميل الزائد هي الحيلة بالنسبة لي.

ومع ذلك، فإن الإعداد الافتراضي يساعد عند التعامل مع Excel Interop، وهو أمر صعب الاستخدام مباشرة خارج الصندوق في C#.

نصائح أخرى

وخلافًا للاعتقاد الشائع، يبدو أن المعلمات الاختيارية متوافقة مع CLS.(ومع ذلك، كان فحصي الأساسي لهذا هو وضع علامة على التجميع والفئة والطريقة جميعًا باستخدام سمة CLSCompliant، المعينة على True.)

إذن كيف يبدو هذا في MSIL؟

.method public static int32  MyMethod(int32 param1,
                                      [opt] int32 param2,
                                      [opt] int32 param3) cil managed
{
  .custom instance void [mscorlib]System.CLSCompliantAttribute::.ctor(bool) = ( 01 00 01 00 00 ) 
  .param [2] = int32(0x00000000)
  .param [3] = int32(0x00000001)
  // Code size       11 (0xb)
  .maxstack  2
  .locals init ([0] int32 MyMethod)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.1
  IL_0003:  add.ovf
  IL_0004:  ldarg.2
  IL_0005:  add.ovf
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method Module1::MyMethod

لاحظ علامات [opt] الموجودة على المعلمات - يدعم MSIL هذا محليًا، دون أي اختراقات.(على عكس دعم MSIL للكلمة الأساسية الثابتة لـ VB، وهو موضوع آخر تمامًا.)

فلماذا لا تكون هذه في C#؟لا أستطيع الإجابة على ذلك، بخلاف تكهناتي بأنه قد يكون نقصًا مفترضًا في الطلب.لقد كان تفضيلي دائمًا هو تحديد المعلمات، حتى لو كانت اختيارية - بالنسبة لي، يبدو الرمز أكثر وضوحًا وأسهل في القراءة.(إذا كانت هناك معلمات محذوفة، فغالبًا ما أبحث أولاً عن التحميل الزائد الذي يطابق التوقيع المرئي - فقط بعد أن أفشل في العثور على واحد أدرك أن المعلمات الاختيارية متضمنة.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top