【问题标题】:How to get the name of class where an object is initialized c#如何获取初始化对象的类的名称c#
【发布时间】:2014-12-23 22:47:37
【问题描述】:

我有几节课。让我们说:

public class A
{
  public void SomeAction()
  {
    Debug.Write("I was declared in class: and my name is:");
  }
}

public class B
{
  public static A myClass = new A();
}

public class C
{
  public static A myClass = new A();
}

public class D
{
  public static A myClass = new A();
}

我想要 A 类中的“SomeAction”做的是打印出它是在哪个类中初始化的。

例如,在我称为C.myClass.SomeAction(); 的另一个类中,它会打印出“我在C 类中被声明,我的名字是myClass

我希望这是有道理的。

我这样做的原因是为了在自动化测试中进行调试。我明白这不是最好的做事方式,而是业务的要求。

【问题讨论】:

  • 您可以在包含“初始化位置”字符串的类上添加一个属性,然后在实例化对象后立即设置该属性。不确定是否有更好的方法,但这是一种方法。 :P
  • 或者你可以使用继承。代替 B、C 和 D 具有 A 的实例,它们可以是 A 的实例。
  • “我明白这不是最好的做事方式,而是业务的要求。” - 我喜欢那条线 :-)
  • 这在静态方法中不起作用
  • 没关系它不应该是静态的

标签: c# class inner-classes


【解决方案1】:

无需继承或传递对象即可满足此要求;我们可以通过检查堆栈从构造函数的主体中获取调用构造函数的类的名称。

public class A
{
    private string _createdBy;

    public void SomeAction()
    {
      Console.WriteLine("I was declared in class [{0}]", _createdBy);
    }

    public A()
    {
      var stackFrame = new StackFrame(1);
      var method = stackFrame.GetMethod();
      _createdBy = method.DeclaringType.Name;
    }
}

在性能方面,我假设您没有创建这些对象的许多实例。您还可以根据您是在进行 DEBUG 构建还是在其他设置上进行预测,以便在您的生产可执行文件中完全跳过这些内容。

【讨论】:

  • @Jonkers,请注意,这种方法可用于进行一些测试或记录器,但速度较慢且不合法。
  • 它仅用于测试自动化。它基本上会生成“非技术”测试人员在测试失败时可以查看的日志文件,因为他们没有 Visual Studio 许可证。不过感谢您的提示。
  • 是否可以使用相同的 StackFrame 来获取已定义类的“名称”?因此,例如,如果我将类的实例初始化为“myA”,我可以使用堆栈帧来获取它吗?
  • @Jonkers 您不能将StackFrame 用于此目的。考虑到许多不同名称的变量可以引用A 的单个实例。
【解决方案2】:

由于您只在其他类中引用类 A 的实例,我认为没有其他方法可以设置对创建类 A 的类型的引用,就像已经提到的 eddie_cat。你可以这样做:

public class B
{
  public static A myClass = new A(typeof(B));
}

然后你的 A 类看起来像:

public class A
{
  // store the parent type
  private Type mParentClass; 

  // provide parent type during construction of A
  public A(Type parentClass)
  {
     mParentClass = parentClass;
  }   

  // note that method cannot be static anymore, since every instance of A might 
  // have a different parent
  public void SomeAction()
  {
     // access field where parent type is stored.
     Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
  }
}

【讨论】:

  • 无论出于何种原因,您需要知道实例的 parent (持有者或创建者),都应该按照这个答案的建议来完成:通过将引用(或至少类型)传递给通过构造函数或属性(属性-因为我喜欢object initializers,虽然它不能保证会设置父级,但这种情况可以单独处理,实际上可能需要)。不是一些肮脏(且缓慢)的堆栈操作。
  • 我不关心速度。它不是性能关键
【解决方案3】:

我认为你有两个选择。要么在 A 中设置一个属性,要么从 A 继承。就我个人而言,我更喜欢从 A 继承,因为这样 A 就可以使用 GetType()。

public class A
{
     public void SomeMethod()
     {
          Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
     }
}

public class B : A
{


}

var instanceOfB = new B();
instanceOfB.SomeMethod();

【讨论】:

  • 将继承用于表示“是一种”关系之外的任何事物都不是一个好主意。
  • this.GetType() 只会得到 A 类
  • @Jonkers 不会的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多