2017-11-21 7 views
4

필자는 log4net 및 log4j의 "format" API 로깅 메시지를 매우 좋아합니다. 따라서 필요한 로그 수준이 설정되지 않은 경우 인수에 ToString()을 호출하는 비용을 피할 수 있습니다.구축하는데 비용이 많이 드는 args와 함께 DebugFormat()을 사용하는 기술이 있습니까?

하지만 사용하는 인수 중 하나 이상이 단순한 개체가 아니라 어떤 방식으로 구성해야하는 경우가 있습니다. 예를 들어, 다음과 같이 : DebugFormat 그것의 있으며, toString 위해하는 것처럼 (해야한다고 결정하지 않는

logger.DebugFormat("Item {0} not found in {1}", 
     itemID, 
     string.Join(",", items.Select(i => <you get the idea>)) 
     ); 

가 실행되지 않도록 (식에 참여) 두 번째 인수를 캡슐화하는 기술이 있는가 첫 번째 인수)?

람다 또는 func 같은 느낌이 들거나 뭔가 도움이 될 것 같지만 C#을 처음 접했을 때 손가락질을 할 수 없었습니다.

+2

그것은이 가능처럼 보이지 않는 - 나는 당신이 그것은처럼 보이는 'Func을 ','Expression' 등을 할 수있는 오버로드를 찾을 수 없습니다 이 시나리오에서는'if (logger.IsDebugEnabled)'를 사용하여 포장하는 다소 조잡한 접근법 만이 실제 옵션 일 수 있습니다. –

+0

log4net 또는 사용자 정의 솔루션에 내장 된 것을 의미합니까? – Evk

+0

델리게이트를 취하는'DebugFormat'에 대한 래퍼를 작성하는 것은 매우 간단합니다. – DavidG

답변

6

확장 메서드 또는 래퍼 클래스를 만들 수 있지만 일부 매개 변수 (예 : itemID)를 명시 적으로 지정하고 일부는 필요한 경우에만 확인하기를 원하기 때문에 만족스러운 구문을 얻는 것은 쉽지 않습니다. 그러나 익명 함수를 object으로 전달할 수는 없습니다. 대신 확장 방법이나 래퍼가 필요없는 다른 솔루션을 사용합니다. 이 같은 클래스를 만듭니다

public sealed class Delayed { 
    private readonly Lazy<object> _lazy; 
    public Delayed(Func<object> func) { 
     _lazy = new Lazy<object>(func, false); 
    } 

    public override string ToString() { 
     var result = _lazy.Value; 
     return result != null ? result.ToString() : ""; 
    } 
} 

이것은 당신이 필요한 경우에만 log4net에 의해 호출됩니다 알고 생성자에서 객체를 반환하고 ToString()가 호출 될 때까지이 함수를 호출하지 않습니다 기능을 허용 (예 : 디버깅 수준이 활성화 된 경우) . 다음과 같이 사용합니다

logger.DebugFormat("Item {0} not found in {1}", 
    itemID, 
    new Delayed(() => string.Join(",", items.Select(i => <you get the idea>))) 
    ); 
+0

이것은 실제로 아주 좋습니다. Func의 배열을 사용하는 확장 메서드를 작성하려고했지만,이 작업이 트릭입니다. – DavidG

+0

'_hasResolved' 등이 아닌'지연'내부에서'지연 성 '을 사용하는 것은 어떻습니까? –

+1

@ serpent5 네, 맞습니다. – Evk