باستخدام StackTrace أن يستنتج الطالب من طريقة

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

  •  11-07-2019
  •  | 
  •  

سؤال

تحرير:تحذير - وأنا أدرك الآن أن تقنية التالية يعتبر عموما فكرة سيئة لأنه يخلق خفية تبعيات أجل تبحث أنيق.


اكتشفت مؤخرا أنه يمكنك استخدام StackTrace لاستنتاج المعلومات عن المتصل من طريقة.

وهذا يتيح لك إنشاء ما يبدو "بارد" API حيث يمكنك ببساطة استدعاء الأسلوب دون عناء لتمرير أي واضحة المعالم ، طريقة يعمل بها ما فعل بناء على StackTrace.

هل هذا شيء سيء القيام به ، و إذا كان الأمر كذلك, لماذا ؟

على سبيل المثال:

public class Cache {
  public Object CheckCache()
  {
    Object valueToReturn = null;
    string key = GenerateCacheKeyFromMethodPrototype(new StackTrace().GetFrame(1).GetMethod()); //frame 1 contains caller
    if(key is in cache) valueToReturn = itemFromCache;

    return valueToReturn;   
  }
}

public class Foo { 
  private static Cache cache = new Cache();

  public Blah MethodFoo(param1, param2...)
  {
    Blah valueToReturn = cache.CheckCache(); //seems cool!
    if(valueToReturn == null)
    {
      valueToReturn = result of some calculation;
      //populate cache
    }

    return valueToReturn;
  }
}

أنا متأكد من أن هناك أخطاء في شبة الكود أعلاه, ولكن يمكنك الحصول على بلدي الانجراف.


تحرير:شكرا لكل الردود.

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

المحلول

هناك سببان لماذا لا تفعل هذا:

  • انها بطيئة
  • إنه يخلق هشة الحل.

إذا كنت تريد أن تفعل هذا, كنت أفضل حالا باستخدام أداة تدعم الجانب برمجة مثل القلعة الوكيل الحيوية.

نصائح أخرى

وثمة مشكلة أخرى هي أن المترجم قد "المضمنة" طريقتك في عملية التحسين، ومنها مثلا.

void MethodA() {
    MethodB();
}

void MethodB() {
   foo();
}

ويصبح:

void MethodA() {
   foo();
}

وهذا هو الواضح مشكلة لأن المتصل مباشرة لفو هو nolonger MethodB، ولكن بدلا من ذلك MethodA. وهناك سمة يمكنك وضع على طريقة لمنع أن يكون inlined على الرغم من:

[MethodImpl( ... NoInline )]

و(لا أستطيع أن أتذكر المعلمة بالضبط)

و-Oisin

وانها سيئة لأنني لا يمكن أن نعرف ما لا وظيفة عندما أسميها. أنا لا يمكن اختبار وظيفة، لأن اختباري سوف يطلق عليه من وظيفة مختلفة، والتي قد استدعاء سلوك مختلف.

وانها سيئة لأنه لا يوجد الآن أي "غير مرئية" عقد يجب أن تطيع عند استدعاء الدالة. ليس فقط لدي لضمان أن يتم تمرير المعلمات الصحيحة، ولدي أيضا للتأكد من أن وظيفة الحالي لديه الاسم الصحيح. ماذا لو كان لي أن التفاف استدعاء دالة في وظيفة امدا مجهول؟ فجأة لقد غيرت سلوك هذا البرنامج، وكان لي <م> لا خمنت أنه في وقت مبكر، وحتى الآن أنا يمكن أن تنفق في اليوم التالي التصحيح لماذا البرنامج اندلعت فجأة وبطريقة سحرية.

وماذا يحدث مع وظائف زائد؟ هل التمييز بينهما؟ وظائف بنفس الاسم، ولكن في فصول مختلفة؟ وظائف مع أسماء "خاصة"، مثل منشئ، finalizer والمشغلين أو lambdas؟

وماذا عن عندما يتم inlined وظائف من قبل المجمع؟

وهذا لا يبدو بارد بالنسبة لي على الإطلاق. لماذا تريد أن تضع كل وسيلة ممكنة للحصول على الدولة المطلوبة في طريقة نفسه؟ هذا هو مثل نمط المضادة للحقن التبعية. لا تذهب إلى هناك.

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