C# 使用反射从父类获取自己的属性名

C# 使用反射从父类获取自己的属性名,c#,reflection,C#,Reflection,是否可以在调用当前类的类中获取该类所分配给的属性的名称 假设我有三门课: class Parent1 { public Child myName; public void Foo() { myName.Method(); } } class Parent2 { public Child mySecondName; public void Foo() { mySecondName.Method(); } } class

是否可以在调用当前类的类中获取该类所分配给的属性的名称

假设我有三门课:

class Parent1
{
   public Child myName;

   public void Foo()
   {
      myName.Method();
   }
}

class Parent2
{
   public Child mySecondName;

   public void Foo()
   {
      mySecondName.Method();
   }
}

class Child
{
   public void Method()
   {
      Log(__propertyName__);
   }
}
当从
Parent1
调用
Method
时,我想
Log
myName
,如果从
Parent2
调用
方法


是否可以使用反射而不是通过在参数中按字符串传递名称(我只想将其用于调试目的,我不想以任何方式将这些类链接在一起)

使用
StackTrace
您至少可以获得进行调用的方法和类:

System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
Type calledFromType = trace.GetFrame(1).GetMethod().ReflectedType;
这将为您提供
Parent1
类型

我认为没有办法获得调用该方法的变量的名称


当然,您可以枚举
calledFromType
的所有字段和属性,并查看其中是否有一个属于
子类型,但您无法保证在调用时实际使用了字段或属性。

由于各种原因,使用反射无法做到这一点:

  • 实例的状态中没有与特定“所有者”相关的内容

  • 您的代码可以从任何可以访问属性的地方调用,因此堆栈跟踪不会可靠地返回任何有用的内容

  • 对类实例的引用可以存储在任意位置,包括方法调用的变量和参数


  • 因此,基本上没有。你能做的最好的事情就是告诉它它在哪里,即使这样,你也会与引用副本发生冲突。

    你不能通过反射来做这件事,但是,你可以使用@James来做这件事,它可能适用于提供给方法的参数——在这种情况下,OP需要包含对被调用类的引用的变量的名称。使用表达式树仍然可以吗?@C.evenhui可能不是直接的,但是您可以有一个采用变量名的
    Log
    方法-很好的例子。@James inside method(),
    等于变量的值-我正试图使用您提供的链接更改我的示例,但它们都需要提供变量。@C.Evenhuis是的,这会引发有关设计的问题。OP想要记录
    这个
    的变量名,正如它在
    Parent1
    中声明的那样-这个概念在我看来是有缺陷的。
    Parent1
    应该是记录器,而不是
    子项
    。请注意,1)使用StackTrace非常昂贵,2)取决于您的构建(调试/发布)由于编译器的优化,您将错过一些东西。请注意,1)使用StackFrame非常昂贵,2)根据您的构建(调试/发布),由于编译器的优化,您将错过一些东西。看,你不能保证那个字段是用来打电话的。在
    Parent1
    中,他可以调用
    newparent2().mySecondName.Method()
    ,您的代码将返回“myFirstName”。同意这两个注释,当然这不是问题的一般解决方案
    class Child
        {
            public void Method()
            {
                StackFrame sf = new StackFrame(1);
                var type = sf.GetMethod().ReflectedType;
    
                var field = type.GetFields().FirstOrDefault(i => i.FieldType == typeof(Child));
    
                Log(field.Name);
            }
        }