是否可以告诉哪个文件在C#中实例化了一个类?
例如,如果我有Page1.cs和Page2.cs,myclass.cs中的构造函数可以知道从哪个页面创建了一个对象吗?
答案 0 :(得分:5)
您可以通过" Caller Information"属性。基本上你在课堂上创建一些额外的可选参数'构造函数,将一些特殊属性应用于它们,编译器将自动为您填写详细信息。例如:
using System.Runtime.CompilerServices;
public MyClass
{
public MyClass(
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
...
}
}
您只需将其称为:
var instance = new MyClass();
并且编译器将自动填写呼叫者的成员名称,文件路径和行号。
答案 1 :(得分:2)
类可以通过在构造期间检查堆栈跟踪来了解实例化它的类。例如,如果您要将其添加到类的构造函数中:
var creator = new StackTrace().GetFrame(1).GetMethod().DeclaringType.FullName;
...您将了解调用new
的代码的位置。位于班级名称中的位置。您当然可以检查声明类型的属性以了解程序集名称,位置等。
请记住,如果你有链式构造函数,你必须进一步走堆栈框架。此外,这不适用于通过反序列化创建的任何对象。
答案 2 :(得分:1)
解决方案1(需要.NET 4.5并编辑代码)
假设这是Caller.cs
public class Caller
{
public Caller()
{
new Callee();
}
}
这是Callee(将被调用的类):
using System.Runtime.CompilerServices;
...
public class Callee
{
public Callee([CallerFilePath] string callerFileName = "")
{
Console.WriteLine(callerFileName);
}
}
输出
c:\users\francesco\source\repos\ConsoleApp19\ConsoleApp19\Caller.cs
更长的解释是例如here; [CallerFilePath]
将负责检索调用者文件名并将其存储在callerFileName
构造函数的Callee
参数中。
这需要编辑源代码和至少.NET 4.5 ,我不确定每个应用程序是否满足要求。
<小时/> 解决方案2(只需编辑代码)
所以,你可以改变Callee
的构造函数来传递一个字符串参数,它将是你的调用者的名字(例如"Caller.cs"
):
public class Caller
{
public Caller()
{
new Callee("Caller.cs");
}
}
public class Callee
{
public Callee(string callerFileName = "")
{
Console.WriteLine(callerFileName );
}
}
如果您只有几个类(Caller
就是其中之一),那么当然这将是一个可行的解决方案,并且可以与.NET框架的每个版本一起使用。
无论如何,不建议使用文件来托管多个类,但是遗留代码中的其他人可能已经完成了这样做:所以你可以得到文件名,但仍然不是调用类,这就是为什么您可以使用我刚刚列出的方法(直接将调用者的名称传递给构造函数)而不是第一个。
<小时/> 解决方案3(无需代码编辑)
最后但并非最不重要的是,如果您只是从Visual Studio进行调试,则不必执行上述任何操作:只需使用StackFrame:为Callee
的构造函数设置断点并单击StackFrame下拉列表:
这将不需要任何代码编辑,并清楚地显示Callee
的构造函数由Caller
调用;你只需点击菜单的任何一行就可以进入主叫线。