宣布一个班级为自己的一员

Kur*_*isu 5 c# oop

我最近在使用C#工作在Microsoft.Ink dll并正在调试一个问题(与此无关)我注意到,当我调试它时,墨水对象有一个笔画对象,它有一个墨水对象, ....等

这让我很困惑,因为我假设你不能这样做(我来自C++背景)

但是我忽略了它,解决了问题,继续前进.今天,我遇到了类似的问题,因为我看了一个有一个私有成员的类,它和它本身是同一个类.

public sealed class Factory
{

    private static Factory instance = new Factory();
}
Run Code Online (Sandbox Code Playgroud)

这怎么可能呢?我现在可以调用instance.instance.instance.instance ...等.正如你可以想象的那样,这伤害了我的大脑,我确信它在计算机上也不会好.编译器如何处理这个问题?兔子洞有多深?

小智 9

因为它是静态的,因此instanceAppDomain中只有一个变量副本.

你在想什么是这样的:

public class Foo
{
  private Foo lol = new Foo();
}
Run Code Online (Sandbox Code Playgroud)

注意,这里的一切都是实例,而不是静态的.

正如评论者所指出的那样(很久以前),这在语法上是有效的,但是会导致抛出StackOverflowException,因为赋值需要构造,而构造会创建一个新的赋值.一个在一个循环中触发另一个循环,该循环在调用堆栈达到其最大长度时结束.

在OP的示例中,赋值需要构造,但赋值由静态构造函数触发,而不是实例构造函数.静态构造函数仅在AppDomain中执行一次,以初始化类'Type.它不是由实例构造触发的,因此(在OP的示例中)不会导致堆栈溢出.

  • 在实例中,它"深入兔子洞"深度足以导致抛出StackOverflowException ... (3认同)

Tim*_*han 7

它本质上不一定是递归的.想一个链表.或一棵树.

class Directory
{
   string name;
   Directory parentDirectory;
}
Run Code Online (Sandbox Code Playgroud)

它只允许该类的对象具有对该类的另一个对象的内部引用.


Ray*_*gus 6

这是一种称为" Singleton " 的软件模式.

有些人对模式的使用不满意,原因多于问题所述,但无论好坏,这都是.NET Framework中的常见模式.您将在要仅实例化一次的类上找到Singleton Properties(或字段).将静态Instance属性视为挂起对象的全局钩子.

  • 单身人士财产不一定必须公开.这只是将类限制为单个实例的一种方法.命名属性"Instance"通常是一个线索,它将被用作Singleton. (2认同)

Ree*_*sey 5

由于这是一个类,而不是结构,因此当您声明一个类的字段时,您只是定义了对类的引用.这允许您在分配参考时继续使用引用.

在你的情况下,你的引用会分配一个新的类,但它是静态的,所以无论你创建了多少个类,它都只会执行一次.实例构造函数在第一次使用Factory时运行,并将调用单个非静态构造函数.不允许执行instance.instance.instance,因为实例是静态的.您无法从成员访问静态变量 - 您需要执行Factory.instance.

但是,你可以〜使实例非静态,并使它成为对其他"Factory"类的引用,甚至是对它的引用.在这种情况下,您可以链接instance.instance.instance - 但只要您设置它们,它就会跟随引用.一切正常,没有问题.