我最近在使用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的示例中)不会导致堆栈溢出.
它本质上不一定是递归的.想一个链表.或一棵树.
class Directory
{
string name;
Directory parentDirectory;
}
Run Code Online (Sandbox Code Playgroud)
它只允许该类的对象具有对该类的另一个对象的内部引用.
由于这是一个类,而不是结构,因此当您声明一个类的字段时,您只是定义了对类的引用.这允许您在分配参考时继续使用引用.
在你的情况下,你的引用会分配一个新的类,但它是静态的,所以无论你创建了多少个类,它都只会执行一次.实例构造函数在第一次使用Factory时运行,并将调用单个非静态构造函数.不允许执行instance.instance.instance,因为实例是静态的.您无法从成员访问静态变量 - 您需要执行Factory.instance.
但是,你可以〜使实例非静态,并使它成为对其他"Factory"类的引用,甚至是对它的引用.在这种情况下,您可以链接instance.instance.instance - 但只要您设置它们,它就会跟随引用.一切正常,没有问题.
| 归档时间: |
|
| 查看次数: |
5899 次 |
| 最近记录: |