سؤال

والنظر في هذا C # قصاصة:

static string input = null;
static string output = null;

static void Main(string[] args)
{
     input = "input";
     output = CallMe(input);
}

public static string CallMe(string input)
{
     output = "output";
     return output;
}

وDissassembling باستخدام البرامج العاكس:

.method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 8
        L_0000: nop 
        L_0001: ldstr "input"
        L_0006: stsfld string Reflector_Test.Program::input
        L_000b: ldsfld string Reflector_Test.Program::input
        L_0010: call string Reflector_Test.Program::CallMe(string)
        L_0015: stsfld string Reflector_Test.Program::output
        L_001a: ret 
    }

 .method public hidebysig static string CallMe(string input) cil managed
    {
        .maxstack 1
        .locals init (
            [0] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "output"
        L_0006: stsfld string Reflector_Test.Program::output
        L_000b: ldsfld string Reflector_Test.Program::output
        L_0010: stloc.0 
        L_0011: br.s L_0013
        L_0013: ldloc.0 
        L_0014: ret 
    }

وقطعة أن يحيرني هو:

L_0010: stloc.0 
L_0011: br.s L_0013
L_0013: ldloc.0 

ويقوم بتخزين هذا البند، والفروع إلى السطر التالي (الذي تم تنفيذه على أي حال) ثم يقوم بتحميل مرة أخرى.

هل هناك سبب لذلك؟

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

المحلول

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

ملاحظة الإصدار ديه IL أكثر إيجازا من ذلك بكثير:

.method private hidebysig static void Main(string[] args) cil managed
{
    .maxstack 8
    L_0000: ldstr "input"
    L_0005: stsfld string Reflector_Test.Program::input
    L_000a: ldsfld string Reflector_Test.Program::input
    L_000f: call string Reflector_Test.Program::CallMe(string)
    L_0014: stsfld string Reflector_Test.Program::output
    L_0019: ret 
}




.method public hidebysig static string CallMe(string input) cil managed
{
    .maxstack 8
    L_0000: ldstr "output"
    L_0005: stsfld string Reflector_Test.Program::output
    L_000a: ldsfld string Reflector_Test.Program::output
    L_000f: ret 
}

نصائح أخرى

وتخميني هو أن هذا هو رمز المتداول لتنفيذ بيان المقابل، المترجم تنفيذ قفزة غير المشروط إلى السطر الأخير، ويحمل قيمة الإرجاع إلى سجل قبل تنفيذ ret. سوف JIT تحسين بطريقة أفضل، وأعتقد أن المترجم لا يكلف نفسه عناء القيام بأي تحقيق أمثلية.

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