سؤال

رأوئون منا الذين عملوا في vb / vb.net قد رأوا كود مماثل لهذه التخزين:

Dim name As String = IIf(obj Is Nothing, "", obj.Name)

أقول "رجس" لأسباب بسيطة:

  1. IIf هو وظيفة, ، كل من المعلمات التي يتم تقييمها؛ وبالتالي إذا obj لا شيء في المكالمة أعلاه ثم NullReferenceException سوف ألقيت. هذا سلوك غير متوقع لشخص اعتاد على مشغلي ثلاثي الدائرة في اللغات مثل C #.
  2. لأن IIf هي وظيفة، وبالتالي فإنه يتحمل النفقات العامة لإجراء مكالمة دالة. مرة أخرى، على الرغم من أن هذه ليست مشكلة كبيرة، إلا أنها لا تشعر بالحق في شخص يتوقع أن تتصرف كعملية ثغرية جوهرية للغة.
  3. IIf غير عامة وبالتالي يقبل معلمات النوع Object, ، مما يعني صناديق المكالمات التالية (أعتقد) ما مجموعه ثلاثة أعداد صحيحة:

    ' boxes 2nd and 3rd arguments as well as return value '
    Dim value As Integer = IIf(condition, 1, -1)

الآن، في بعض الإصدار الأخير من VB.NET (لست متأكدا من رقم الرقم)، If تم تقديم المشغل، الذي يعمل بالضبط بنفس الطريقة مثل IIf وظيفة ولكن (كما أفهمها) دون أوجه القصور نفسها. وهذا يعني ذلك هل توفير الدائرة القصيرة وذلك يكون عملية vb intrinstic. ومع ذلك، لست متأكدا من الجزء الأخير. ال وثائق MSDN. لا يبدو أن يشير إلى ما إذا كان If صناديق حججها أم لا. هل يعلم أحد؟

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

المحلول

الشيء الرئيسي هو أنك حددت بشكل صحيح الجديد If كما المشغل أو العامل بدلا من وظيفة. كما أنه لا يحتاج إلى ملاكمة، وبالتالي لا يحتاج إلى ملاكمة، وهو رسم خرائط مباشرا على الشرط / القصير /؟ المشغل في C / C ++ / C # / Java / etc

حتى بدون المشغل الجديد، يمكنك الحصول على بعض التحسن في VB.NET مع هذا الرمز:

Public Shared Function IIf(Of T)(ByVal Expression As Boolean, ByVal TruePart As T, ByVal FalsePart As T) As T
    If Expression Then Return TruePart Else Return FalsePart
End Function

نصائح أخرى

فازت Joel على إجابة، ولكن هنا هو برنامج عينة وإلغاء إيل ينشئ أنه إذا تم () تمر () من خلال المشغل الثلاثي الأساسي ل IL دون ملاكمة.

Public Class Test
    Public Sub New()
        Dim rnd = New Random()
        Dim result As Integer = If(rnd.Next(1000) < 500, 1, -1)
        Console.WriteLine(result)
    End Sub
End Class

كما ترى IL لا يوجد لديه بيان "مربع".

.method public specialname rtspecialname instance void .ctor() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 result,
        [1] class [mscorlib]System.Random rnd)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: call instance void [mscorlib]System.Object::.ctor()
    L_0007: nop 
    L_0008: newobj instance void [mscorlib]System.Random::.ctor()
    L_000d: stloc.1 
    L_000e: ldloc.1 
    L_000f: ldc.i4 0x3e8
    L_0014: callvirt instance int32 [mscorlib]System.Random::Next(int32)
    L_0019: ldc.i4 500
    L_001e: blt.s L_0023
    L_0020: ldc.i4.m1 
    L_0021: br.s L_0024
    L_0023: ldc.i4.1 
    L_0024: stloc.0 
    L_0025: ldloc.0 
    L_0026: call void [mscorlib]System.Console::WriteLine(int32)
    L_002b: nop 
    L_002c: nop 
    L_002d: ret 
}

بالنظر إلى نفس البرنامج ولكن باستخدام وظيفة IIF القديمة ()، يتم إنتاج IL التالي. يمكنك أن ترى كل من الملاكمة، ودالة استدعاء النفقات العامة:

.method public specialname rtspecialname instance void .ctor() cil managed
{
    .maxstack 3
    .locals init (
        [0] int32 result,
        [1] class [mscorlib]System.Random rnd)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: call instance void [mscorlib]System.Object::.ctor()
    L_0007: nop 
    L_0008: newobj instance void [mscorlib]System.Random::.ctor()
    L_000d: stloc.1 
    L_000e: ldloc.1 
    L_000f: ldc.i4 0x3e8
    L_0014: callvirt instance int32 [mscorlib]System.Random::Next(int32)
    L_0019: ldc.i4 500
    L_001e: clt 
    L_0020: ldc.i4.1 
    L_0021: box int32
    L_0026: ldc.i4.m1 
    L_0027: box int32
    L_002c: call object [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::IIf(bool, object, object)
    L_0031: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToInteger(object)
    L_0036: stloc.0 
    L_0037: ldloc.0 
    L_0038: call void [mscorlib]System.Console::WriteLine(int32)
    L_003d: nop 
    L_003e: nop 
    L_003f: ret 
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top