C#类是否知道实例化了哪个文件?

时间:2018-04-22 08:38:36

标签: c#

是否可以告诉哪个文件在C#中实例化了一个类?

例如,如果我有Page1.cs和Page2.cs,myclass.cs中的构造函数可以知道从哪个页面创建了一个对象吗?

3 个答案:

答案 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下拉列表:

StackFrame dropdown

这将不需要任何代码编辑,并清楚地显示Callee的构造函数由Caller调用;你只需点击菜单的任何一行就可以进入主叫线。