log4net อาร์กิวเมนต์ไปยัง LogManager.GetLogger


98

เหตุใดตัวอย่าง log4net ส่วนใหญ่จึงรับคนตัดไม้สำหรับคลาสโดยทำสิ่งนี้:

private static ILog logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

แทนที่จะส่งผ่าน typeof (MyClass):

private static ILog logger = LogManager.GetLogger(typeof(MyClass));

มีเหตุผลอื่นในการทำเช่นนี้นอกเหนือจากข้อเท็จจริงที่ว่าตัวเลือกแรกไม่ต้องการให้คุณพิมพ์ชื่อคลาสเฉพาะหรือไม่?

คำตอบ:


93

ฉันคิดว่าคุณมีเหตุผล ฉันทำแบบนั้นดังนั้นฉันจึงไม่ต้องกังวลกับชื่อชั้นเรียนและสามารถคัดลอกและวางรหัสแผ่นหม้อไอน้ำในคลาสใหม่ได้

สำหรับคำตอบอย่างเป็นทางการโปรดดูที่: ฉันจะรับชื่อที่มีคุณสมบัติครบถ้วนของคลาสในบล็อกแบบคงที่ได้อย่างไร ที่คำถามที่พบบ่อยของ log4net


โอเคเคลียร์ได้แล้วขอบคุณสำหรับลิงค์นั้นฉันไม่เคยเห็นมาก่อน
Andy White

มันเก่าพอ ๆ กับมัน แต่ลองดูคำตอบของฉันในกรณีที่คุณยังคงวางเป็นรหัสหม้อไอน้ำ :)
Noctis

คุณประหยัดเวลาในการพัฒนาและวางโค้ดนี้ได้เล็กน้อย อย่างไรก็ตามมีค่าใช้จ่ายในการเรียก 'GetCurrentMethod ()' ซึ่งต่างจากการใช้ค่าคงที่ของสตริงหรือการเรียก 'typeof ()' หากคุณบวกจำนวนครั้งที่จะเรียกสิ่งนี้ตลอดอายุการใช้งานของรหัสเทียบกับระยะเวลาที่คุณจะพิมพ์ชื่อคลาสฉันคิดว่าคุณแค่ทำให้โค้ดของคุณช้าลงเพื่อประโยชน์เพียงเล็กน้อย
Youngs

1
คุณไม่ได้ช้าลงอย่างที่คิดนี่เป็นการโทรแบบคงที่ดังนั้นคุณจึงมีการเรียกหนึ่งครั้งต่อคลาสต่อโดเมนของแอปเช่นหากคุณมีคลาส 300 คลาสคุณจะมีการโทรมากที่สุด 300 ครั้งตลอดอายุแอปของคุณ
Paul Hatcher

ไม่มีจุดที่จะใช้การสะท้อนเพื่อให้ได้ชื่อประเภทและสำเนา / อดีตคือความเกียจคร้านและคุณได้รับผลงานที่ยอดเยี่ยมดังนั้นทำไมไม่ใช้แค่ชื่อ!
MeTitus

8

ฉันเป็นผู้ใช้ NLog และโดยปกติสิ่งนี้จะเกิดขึ้นที่:

var _logger = LogManager.GetCurrentClassLogger();

มันดูแปลกนิดหน่อยที่คุณต้องผ่านการไตร่ตรองใน Log4Net ดังนั้นฉันจึงดูซอร์สโค้ด NLog และดูเถิดนี่คือสิ่งที่พวกเขาทำเพื่อคุณ:

[MethodImpl(MethodImplOptions.NoInlining)]
public static Logger GetCurrentClassLogger()
{
    string loggerName;
    Type declaringType;
    int framesToSkip = 1;
    do
    {
#if SILVERLIGHT
        StackFrame frame = new StackTrace().GetFrame(framesToSkip);
#else
        StackFrame frame = new StackFrame(framesToSkip, false);
#endif
        var method = frame.GetMethod();
        declaringType = method.DeclaringType;
        if (declaringType == null)
        {
            loggerName = method.Name;
            break;
        }
        framesToSkip++;
        loggerName = declaringType.FullName;
    } while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
    return globalFactory.GetLogger(loggerName);
}

ฉันเดาว่าฉันจะเขียนสิ่งที่คล้ายกันสำหรับ Log4Net เป็นส่วนขยายหรือวิธีการคงที่แทนที่จะวางภาพสะท้อนเป็นส่วนหนึ่งของรหัสหม้อไอน้ำของฉัน :)


7

อย่างที่คุณพูด - สะดวกเพราะคุณสามารถสร้างคนตัดไม้ด้วยวิธีการโดยไม่ต้องรู้ชื่อของคลาส (ฉันรู้เล็กน้อย) แต่ช่วยให้คุณสามารถตัดและวางวิธีการระหว่างคลาสได้โดยไม่ต้องเปลี่ยนชื่อการโทร


3

ฉันคิดว่าเหตุผลคือคุณได้รับประเภทของประเภทรันไทม์โดยใช้.DeclaringType()วิธีการ คุณสามารถใช้คนตัดไม้ในคลาสพื้นฐานและยังคงเห็นชนิดจริงของวัตถุของคุณในเอาต์พุตตัวบันทึก นั่นทำให้การสืบสวนมีความสะดวกมากขึ้น


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.