2017-07-07 27 views
1

我想傳遞一個值調用一個函數,但要忽略真正將其添加爲參數時。自動傳遞自己的類型,函數調用

更準確地說我想寫也打印哪一類稱爲日誌記錄功能,但不希望總是通過一個「本」作爲一個參數的記錄器。

示例代碼:

class static Logger{ 
    public static void LogMsg(string msg, object objectCalling){ 
     Print(objectCalling.GetType().Name + ": " + msg); 
    } 
    private void Print(string msg){ 
     // print it 
    } 
} 

class SomeClass{ 
    private void WriteTestLog() { 
     Logger.LogMsg("Testing!"); 
    } 
} 

這應該然後創建等的輸出: 「SomeClass的:測試」

我不知道該如何處理這個也許我只是缺少某事。

+4

最接近你可以*可靠*是與CallerMemberInfo屬性。請參閱https://stackoverflow.com/questions/171970。 (你可以得到堆棧跟蹤,但是在內聯中這是不可靠的,並且性能受到影響。) –

回答

1

有幾個屬性可能會有所幫助:

  • CallerMemberNameAttribute:調用方法或屬性的名稱;
  • CallerFilePathAttribute:其中主叫構件是在文件路徑;
  • CallerLineNumberAttribute:文件內的行號。

如您所見,類名不存在任何屬性,但是對於文件路徑,您可能會獲得相同級別的信息。

如何使用?使用屬性在日誌記錄方法中裝飾參數(當然,使用正確的類型和默認值)。

public static void LogMsg(string msg, [CallerMemberName] string callingMember = null) 
{ 
    Print($"{callingMember}: {msg}"); 
} 

而且只要致電:

LogMsg("hello!"); 
+0

好的,是的,這似乎是對我來說最合理的方法。謝謝。 – GarretGarner

2

您可以使用System.Runtime.CompilerServices與它的CallerMemberNameAttribute

這裏是例子:

using System; 
using System.Runtime.CompilerServices; 

namespace ConsoleApp3 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Logger.WriteLog("Hello"); 
     } 

    } 
    public class Logger 
    { 
     public static void WriteLog(string msg, [CallerMemberName] string methodName="") 
     { 
      Console.WriteLine("Method:{0}, Message: {1}",methodName,msg); 
     } 
    } 
} 
+0

這是方法名稱,而不是類名稱。 –

0

您可以創建一個擴展方法,這樣做的以及上面的答案:

void Main() 
{ 
SomeClass x = new SomeClass(); 
x.WriteTestLog(); 

int i = 1; 
i.LogMsg("abc"); 
} 

public static class Logger 
{ 
    public static void LogMsg(this object objectCalling, string msg) 
    { 
     Print(objectCalling.GetType().Name + ": " + msg); 
    } 
    private static void Print(string msg) 
    { 
    Console.WriteLine(msg); // print it 
    } 
} 

public class SomeClass 
{ 
    public void WriteTestLog() 
    { 
    this.LogMsg("Testing!"); 
    } 
} 
+0

有趣的是,這幾乎是它。但是我發現每個具有LogMsg函數的對象都有點奇怪。 – GarretGarner

0

如果你真的希望提取呼叫者的類型,你可以用堆棧跟蹤玩:

[MethodImpl(MethodImplOptions.NoInlining)] 
public static void LogMsg(string msg) 
{ 
    var caller = new StackTrace().GetFrames()[1].GetMethod(); 
    Console.WriteLine($"{caller.DeclaringType}.{caller.Name}: {msg}"); 
} 

但是請記住,從堆棧跟蹤提取來電者是一個非常昂貴的操作。除了NoInlining之外,不保證在優化版本中調用者本身沒有內聯。我不建議在發佈版本中使用它,或者如果性能很重要。