2016-06-10 4 views
1

Ich habe einige Methoden, die aus dem Einstiegspunkt einer WinForms-App aufgerufen werden. Diese Methoden wiederum rufen andere und manchmal auch einander an.Code direkt vor der Kompilierung in C# -Methoden einfügen

Am Eingang jeder Methode habe ich Code wie folgt eingefügt:

public static bool IsDebug 
{ 
    #if (DEBUG) 
     return (true); 
    #else 
     return (false); 
    #endif 
} 

public void SomeMethod() 
{ 
    if (IsDebug) { Logger.WriteMethodTrace(MethodBase.GetCurrentMethod().Name); } 
} 

Es gibt zwei Probleme mit diesem Ansatz:

  • Es wird von Hand in jede Methode geschrieben wird.
  • Es verwendet Reflexion, die für häufig aufgerufene Methoden zu langsam ist.

.
REFLEXION: Das neue C# nameof(parameter) Schlüsselwort funktioniert gut für Parameternamen, aber ich habe kein ähnliches Konstrukt für Methodennamen gefunden. Ich dachte darüber nach, eine Art von statischem Wörterbuch zu erstellen, das Type und MethodInfo Details enthält, aber es scheint keine Möglichkeit zu geben, den Methodennamen zur Laufzeit ohne Reflektion zu extrahieren, um sie als Schlüssel im Wörterbuch zu verwenden.

SCHRIFTLICH VON HAND: Selbst wenn es eine Lösung zur Vermeidung von Reflexion gäbe, müsste jede Methode von Hand geändert werden, was mühsam und fehleranfällig ist. Ich habe mich gefragt, ob es eine Möglichkeit gibt, eine Codezeile just-in-time vor der Kompilierung einzufügen. Nicht sicher ist eine VS-Erweiterung oder Roslyn würde hier helfen. Wenn Auto-Insertion möglich ist, sollte die Insertion idealerweise ohne Änderung des Quellcodes erfolgen.

Bitte beachten Sie, dass die Analyse des Stack-Trace keine Option ist. Ich bin diesen Weg gegangen und es ist langsam und unangenehm.

Alle Hinweise/Vorschläge würden geschätzt.

+2

Sie können AOP (Aspect Oriented Programming) Paradigma verwenden. Der bekannteste Vertreter in C# world ist PostSharp. Seine kostenlose Version kann tun, was Sie wollen. – Evk

+0

Warum nicht einfach einen TraceListener verwenden und ihn je nach Bedarf in app.config ein- oder ausschalten? – Oscar

+0

@Evk: Obwohl die Frage beantwortet wurde, scheint PostSharp ein guter Vorschlag zu sein. Vielen Dank! –

Antwort

4

C# 5.0 hat eine nette Funktion für Sie. Ich denke, es ist sehr nützlich sein wird für Dich, dies zu versuchen:

[Conditional("DEBUG")] 
public void LogMethodNameInDebug(
    [CallerMemberName] string memberName = "", 
    [CallerFilePath] string sourceFilePath = "", 
    [CallerLineNumber] int sourceLineNumber = 0) 
{ 
    Logger.WriteMethodTrace(memberName); 
) 


public void SomeMethod() 
{ 
    LogMethodNameInDebug(); // don't fillin the methodnames yourself, the compiler will do. 
} 

Die [Conditional("DEBUG")] wird das Verfahren auszuschließen, wenn es als ein Releasebuild kompilieren. Geben Sie für weitere Informationen: MSDN - ConditionalAttribute

Und die [CallerMemberName] wird gefüllt compiletime (es die Parameter auf den Anrufer füllt, so dass keine Reflexion oder Stapel Analyse verwendet wird). Weitere Informationen über [CallerMemberName] hier: MSDN - CallerMemberNameAttribute

+0

Nitpick: das ist eine Funktion von C# 5.0, nicht .Net 4.5. – svick

+0

@ Jeroen, Danke! Dies ist perfekt. Darüber hinaus könnte ich eine Roslyn-basierte Erweiterung verwenden, um sicherzustellen, dass diese Methode zu Beginn jeder Funktion aufgerufen wird. –

+0

@svick msdn sagt 'Verfügbar seit 4.5'. Ich weiß, vorausgesetzt, es ist schlecht ... –

Verwandte Themen