如何获取调用我的方法的类名? [复制]
Posted
技术标签:
【中文标题】如何获取调用我的方法的类名? [复制]【英文标题】:How to get Class name that is calling my method? [duplicate] 【发布时间】:2018-07-12 05:45:30 【问题描述】:我想编写自己的记录器。
这是我的记录器管理员:
public static class LoggerManager
public static void Error(string name)
我正在调用Error(string name);
方法如下:
public class Foo
public void Test()
LoggerManager.Error(this.GetType().FullName);
通过这种方式,我在名为Error
的方法中获取调用者类名。
但我不想每次都将名称传递给错误方法。我想让我的记录器(或其他记录器方法:Info()
、Warn()
)方法自己获取名称。
感谢您的最佳实践...
【问题讨论】:
查看副本,但不是调用.Name
而是调用.DeclaringType
来获取Type
实例,然后您可以获得名称、全名、程序集信息等等。
我投票重开这个问题。 OP想要获取调用者类而不是方法。
但是你可以很容易地得到定义方法的类,不是吗?如果我们重新打开这个问题,人们可能还会问如何获取命名空间或如何获取定义属性的类。只是因为这个问题不适合确切的用例,它才能回答这个问题。
@HimBromBeere,我不同意你的看法。当然,我们可以通过引用的问题轻松获取类名,但是关于获取类名的问题非常清楚。无论如何,引用的答案并不适合确切的答案。
重点是,如果我们正在寻找 exactly 匹配上下文的重复项,那么我们不太可能找到 any 重复项,因为上下文可能与副本中的内容略有不同。
【参考方案1】:
您可以使用CallerMemberName
和CallerFilePath
属性
public static void Log(string text, [CallerMemberName] string caller = "", [CallerFilePath] string file = "")
WriteLog(text, caller, file);
Log("Something happened");
另见CallerLineNumber
顺便说一句:您可能希望将昂贵的 StackFrame 的速度与内置属性进行比较。
int num = 500000;
var t1 = Measure(() => NameOfCallingClass(), num); //<-- 9000
var t2 = Measure(() => Log("aa"), num); //<--26
long Measure(Action func, int num)
func();
var sw = Stopwatch.StartNew();
for (int i = 0; i < num; i++)
func();
return sw.ElapsedMilliseconds;
【讨论】:
来电者信息属性不回答问题。他想要类名,而不是成员名或驻留类的文件路径。使用 stackframe voodoo 是目前唯一已知的方法。此外,使用 [CallerFilePath] 将获取文件编译时的路径。总而言之,在生产日志中这看起来像垃圾。 类似 csproj 中的string callerClassName = Path.GetFileNameWithoutExtension(callerFilePath);
将适用于类名,假设文件名对应于包含的类名。【参考方案2】:
你可以使用System.Diagnostics
的StackFrame和System.Reflection
的MethodBase。
StackFrame(Int32, Boolean)
初始化StackFrame
类的新实例,该实例对应于当前堆栈帧上方的帧,可选择捕获源信息。
MethodBase
,提供有关方法和构造函数的信息。
public static string NameOfCallingClass()
string fullName;
Type declaringType;
int skipFrames = 2;
do
MethodBase method = new StackFrame(skipFrames, false).GetMethod();
declaringType = method.DeclaringType;
if (declaringType == null)
return method.Name;
skipFrames++;
fullName = declaringType.FullName;
while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
return fullName;
您的记录器类调用此方法:
public static void Error()
string name = NameOfCallingClass();
【讨论】:
谢谢你。这看起来处理的不仅仅是获取 Method.DeclaringType - 您能否添加一些解释,说明为什么需要 While 循环以及为什么需要检查“mscorlib.dll”? 在 C# 聊天中,@TomW 提供了帮助:declaringType = method.DeclaringType
获得了类名。 while
循环通过递增skipFrames
来查找堆栈,查找调用类型不在mscorlib.dll
中的第一帧。换句话说,它不是 Microsoft 课程,而是您自己的课程。【参考方案3】:
您可以从 StackTrace
实例中获取它。
public static class LoggerManager
public static void Error()
var methodInfo = new StackTrace().GetFrame(1).GetMethod();
var clasName = methodInfo.ReflectedType.Name;
【讨论】:
GetFrame(1) 返回LoggerManager
。 GetFrame(2) 返回 Foo
。 @kabul 想得到Foo
。以上是关于如何获取调用我的方法的类名? [复制]的主要内容,如果未能解决你的问题,请参考以下文章