是否可以确定实例化类的当前实例的类的哪个实例?

时间:2015-12-01 08:25:16

标签: c#

正如标题所示,可以确定实例化另一个类的特定实例的类的哪个实例?

更新:下面的示例代码

class FooBar: Foo
{
    private Context context;
    public FooBar(Context _context): base(_context)
    {
        this.context = _context;
    }
}

class Foo
{
    public Baz baz;
    private Context context; 
    public Foo(Context _context)
    {
        baz = new Baz();
        this.context = _context;
    }
}

class Baz
{
    public Baz()
    {
        GetNameOfCaller()
    }

    private void GetNameOfCaller()
    {
       ....
       ....
       _className = ....;
    }
    private string _className;
}

3 个答案:

答案 0 :(得分:7)

是的,您可以像常规方法一样为构造函数执行此操作。只需使用CallerMemberName传递调用方法的名称即可。你不会有它的类名,那么你需要走StackTrace这更复杂。

public class X
{
    public X([CallerMemberName] string caller = null)
    {
        this.Caller = caller;
    }

    public string Caller { get; private set; }
}

然后就这样打电话。编译器将为您填写caller参数:

static void Main(string[] args)
{
    X x = new X();
    Console.WriteLine($"Caller = {x.Caller}"); // prints Main
}

答案 1 :(得分:4)

您可以使用System.Diagnostics.StackTrace

public class Foo 
{
    public void MethodBah()
    {
        System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();
        MethodBase callingMethod = t.GetFrame(1).GetMethod();
        Type callingMethodType = callingMethod.DeclaringType;
        string className = callingMethodType.Name;
    }
}

即使在.NET 1.1中也能正常工作。

使用您的(已更新)示例,您必须使用t.GetFrame(2).GetMethod()代替GetFrame(1)来获取FooBar而不是Foo,因为子调用父构造函数。

答案 2 :(得分:2)

我相信您的要求应该使用aspect-oriented programming来解决。

OP在一些评论中表示:

  

[..]现在记录目的但可能不仅限于它[...]

例如,有一个非常强大的工具叫PostSharp,它可以让你拦截任何方法调用,当它被调用时和调用之后:

[Serializable]
public class LogAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
    }

    public override void OnExit(MethodExecutionArgs args)
    {
    }
}

现在,您可以将整个方面作为常规属性应用于方法,类或甚至应用于程序集(因此,程序集中的所有方法都将 loggable )。

您可以通过MethodExecutionArgs.Method(类型为MethodBase)访问被调用的方法,这意味着您可以访问哪种类型通过MethodBase.DeclaringType声明整个方法。

使用像PostSharp这样的工具,您可以添加额外的编译步骤,但它具有在编译时注入拦截的巨大优势。也就是说,它会像在每种方法中手动添加整个代码一样。

您还可以使用Castle DynamicProxy创建运行时代理来拦截方法调用。