我不想再傳遞 nameof 了

2023-02-16 09:00:37

有的時候丟擲一個異常,我們需要知道是哪個方法丟擲的異常。那麼,我們可以通過傳遞 nameof 來獲取呼叫者的方法名。但是,感覺很煩,每次都要傳遞 nameof。那麼,有沒有更好的方法呢?

CallerLineNumberAttribute

獲取呼叫者的行號。

using System;
using System.Runtime.CompilerServices;

public static class Program
{
   public static void Main()
   {
      TraceMessage("Something happened.");
   }

   public static void TraceMessage(string message,
                        [CallerLineNumber] int sourceLineNumber = 0)
   {
      Console.WriteLine("Line: {0} - {1}", sourceLineNumber, message);
   }
}
// The example displays the following output:
//    Line: 10 - Something happened.

CallerFilePathAttribute

獲取呼叫者的檔案路徑。

using System;
using System.IO;
using System.Runtime.CompilerServices;

public static class Program
{
   public static void Main()
   {
      TraceMessage("Something happened.");
   }

   public static void TraceMessage(string message,
                        [CallerFilePath] string sourceFilePath = "")
   {
      Console.WriteLine("File: {0} - {1}", Path.GetFileName(sourceFilePath), message);
   }
}
// The example displays the following output:
//    File: Program.cs - Something happened.

可發帖可群聊的技術交流方式已經上線,歡迎通過連結,加入我們一起討論。 https://www.newbe.pro/links/

CallerMemberNameAttribute

獲取呼叫者的方法名。

using System;
using System.Runtime.CompilerServices;

public static class Program
{
   public static void Main()
   {
      DoProcessing();
   }

   public static void DoProcessing()
   {
      TraceMessage("Something happened.");
   }

   public static void TraceMessage(string message,
                        [CallerMemberName] string memberName = "")
   {
      Console.WriteLine("Member: {0} - {1}", memberName, message);
   }
}
// The example displays the following output:
//    Member: DoProcessing - Something happened.

CallerArgumentExpressionAttribute

獲取呼叫者的參數列達式。C# 10.0 新增。

這個其實很好用,以後再也不用擔心 ArgumentException 還需要寫一個 nameof 了。

using System;
using System.Runtime.CompilerServices;

public static class Program
{
   public static void Main()
   {
      int x = 10;
      int y = 20;
      Assert(x > y, "x > y");
   }

   public static void Assert(bool condition, [CallerArgumentExpression("condition")] string message = null)
   {
      Console.WriteLine("Condition: {0} - {1}", condition, message);
   }
}
// The example displays the following output:
//    Condition: False - x > y

總結

通過上面的幾個例子,我們可以看到,藉助在編譯時獲取呼叫者的行號、檔案路勁和呼叫者方法名的特性,我們可以在開發中更加方便的進行紀錄檔記錄。

參考

感謝您的閱讀,如果您覺得本文有用,請點贊、關注和轉發。

可發帖可群聊的技術交流方式已經上線,歡迎通過連結,加入我們一起討論。 https://www.newbe.pro/links/


  1. https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callerlinenumberattribute?view=net-7.0&WT.mc_id=DX-MVP-5003606

  2. https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callerfilepathattribute?view=net-7.0&WT.mc_id=DX-MVP-5003606

  3. https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callermembernameattribute?view=net-7.0&WT.mc_id=DX-MVP-5003606

  4. https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute?view=net-7.0&WT.mc_id=DX-MVP-5003606