调用一个共同的功能
问题描述:
我不太确定如何最好问这个问题,所以请随时编辑获取类/方法名称...调用一个共同的功能
我已经使用了包含常用功能的“实用工具”类贯穿我的申请。我的一个方法记录产生的异常这样的:
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);
答
请注意,frame.GetMethod().DeclaringType
可以返回null
:前一段时间我面临这个问题只在发布使用NLog logger(GetCurrentClassLogger
)建立我的应用程序的。不能完全记住这种情况。顺便说一下,它是known issue。
Apache log4net有一个有趣的技巧,它允许检测来电者信息(类,方法等)。
请看看:
-
LocationInfo
类(source) - 主叫用户位置信息的内部表示。public class LocationInfo { ... public LocationInfo(Type callerStackBoundaryDeclaringType) { // Here is the trick. See the implementation details here. } ... }
-
LogImpl
类(source) - 记录器的实现类 - 来包裹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); } ... }