C# 获取调用公共函数的类/方法名称

C# 获取调用公共函数的类/方法名称,c#,.net,visual-studio-2010,logging,typeof,C#,.net,Visual Studio 2010,Logging,Typeof,我不太确定如何最好地问这个问题,所以请随意编辑 我有一个“Utilities”类,它包含在整个应用程序中使用的通用功能。我的一个方法记录了如下示例: internal static void logExeption(Type typeOfClass, string methodName, Exception exeption ) { //Do some logging here } 然后,每当我发现这样的异常时,我希望在整个应用程序中调用它: try{ //perform som

我不太确定如何最好地问这个问题,所以请随意编辑

我有一个“Utilities”类,它包含在整个应用程序中使用的通用功能。我的一个方法记录了如下示例:

internal static void logExeption(Type typeOfClass, string methodName, Exception exeption )
 {
   //Do some logging here
 }
然后,每当我发现这样的异常时,我希望在整个应用程序中调用它:

try{
  //perform some action
}
catch(Exception ex)
{
Utils.logExeption(this.GetType(), System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
 }

我想知道是否有一种方法可以避免传入前两个参数,只需找出异常发生在logException方法中的类/方法的上下文。从长远来看,这将使事情变得更干净。

因此您需要确定调用对象和函数。虽然不建议这样做,但它是可以实现的。使用System.Diagnostics.StackTrace遍历堆栈;然后将适当的StackFrame提升一级。然后在StackFrame上使用GetMethod()确定调用方是哪个方法。请注意,构建堆栈跟踪是一项潜在的昂贵操作,方法的调用者可能会模糊事情的真正来源

StackFrame frame = new StackFrame(1);
MethodBase method = frame.GetMethod();
string message = String.Format("{0}.{1} : {2}",
method.DeclaringType.FullName, method.Name, message);
Console.WriteLine(message);

因此,您需要确定调用对象和函数。虽然不建议这样做,但它是可以实现的。使用System.Diagnostics.StackTrace遍历堆栈;然后将适当的StackFrame提升一级。然后在StackFrame上使用GetMethod()确定调用方是哪个方法。请注意,构建堆栈跟踪是一项潜在的昂贵操作,方法的调用者可能会模糊事情的真正来源

StackFrame frame = new StackFrame(1);
MethodBase method = frame.GetMethod();
string message = String.Format("{0}.{1} : {2}",
method.DeclaringType.FullName, method.Name, message);
Console.WriteLine(message);

你可以用。请参见与您的问题非常相似的示例。

您可以使用。请注意,
frame.GetMethod().DeclaringType
可以返回
null
:不久前,我只在使用(
GetCurrentClassLogger
)发布应用程序时遇到了这个问题。我记不清确切的情况了。顺便说一下,是的

有一个有趣的技巧允许检测调用方信息(类、方法等)

请看:

  • LocationInfo
    class()-调用方位置信息的内部表示

     public class LocationInfo
     {
         ...
    
         public LocationInfo(Type callerStackBoundaryDeclaringType)
         {
             // Here is the trick. See the implementation details here.
         }
    
         ...
     }
    
  • LogImpl
    class()-记录器实现类-围绕ILogger接口的包装器-要实现这个技巧,它不能被子类化

     public class LogImpl : LoggerWrapperImpl, ILog
     {
         ...
         public LogImpl(ILogger logger) : base(logger)
         {
             ...
         }
    
         /// <summary>
         /// The fully qualified name of this declaring type not the type of any subclass.
         /// </summary>
         private readonly static Type ThisDeclaringType = typeof(LogImpl);
    
         virtual public void Error(object message, Exception exception)
         {
             Logger.Log(ThisDeclaringType, m_levelError, message, exception);
         }
    
         ...
     }
    
    公共类LogImpl:LoggerWrapperImpl,ILog { ... 公共LogImpl(ILogger记录器):基本(记录器) { ... } /// ///此声明类型的完全限定名不是任何子类的类型。 /// 私有只读静态类型ThisDeclaringType=typeof(LogImpl); 虚拟公共无效错误(对象消息、异常) { Logger.Log(ThisDeclaringType、m_levelError、message、exception); } ... }

  • 请注意,
    frame.GetMethod().DeclaringType
    可以返回
    null
    :不久前,我只在使用(
    GetCurrentClassLogger
    )发布应用程序时遇到了这个问题。我记不清确切的情况了。顺便说一下,是的

    有一个有趣的技巧允许检测调用方信息(类、方法等)

    请看:

  • LocationInfo
    class()-调用方位置信息的内部表示

     public class LocationInfo
     {
         ...
    
         public LocationInfo(Type callerStackBoundaryDeclaringType)
         {
             // Here is the trick. See the implementation details here.
         }
    
         ...
     }
    
  • LogImpl
    class()-记录器实现类-围绕ILogger接口的包装器-要实现这个技巧,它不能被子类化

     public class LogImpl : LoggerWrapperImpl, ILog
     {
         ...
         public LogImpl(ILogger logger) : base(logger)
         {
             ...
         }
    
         /// <summary>
         /// The fully qualified name of this declaring type not the type of any subclass.
         /// </summary>
         private readonly static Type ThisDeclaringType = typeof(LogImpl);
    
         virtual public void Error(object message, Exception exception)
         {
             Logger.Log(ThisDeclaringType, m_levelError, message, exception);
         }
    
         ...
     }
    
    公共类LogImpl:LoggerWrapperImpl,ILog { ... 公共LogImpl(ILogger记录器):基本(记录器) { ... } /// ///此声明类型的完全限定名不是任何子类的类型。 /// 私有只读静态类型ThisDeclaringType=typeof(LogImpl); 虚拟公共无效错误(对象消息、异常) { Logger.Log(ThisDeclaringType、m_levelError、message、exception); } ... }