加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何设计一个类来防止循环依赖在构造之前调用派生成员?

发布时间:2020-12-15 08:18:11 所属栏目:百科 来源:网络整理
导读:(我将它标记为C#和 Java,因为它在两种语言中都是相同的问题.) 说我有这些课程 interface IKernel{ // Useful members,e.g. AvailableMemory,TotalMemory,etc.}class Kernel : IKernel{ private /*readonly*/ FileManager fileManager; // Every kernel has 1
(我将它标记为C#和 Java,因为它在两种语言中都是相同的问题.)

说我有这些课程

interface IKernel
{
    // Useful members,e.g. AvailableMemory,TotalMemory,etc.
}

class Kernel : IKernel
{
    private /*readonly*/ FileManager fileManager;  // Every kernel has 1 file manager
    public Kernel() { this.fileManager = new FileManager(this); /* etc. */ }

    // implements the interface; members are overridable
}

class FileManager
{
    private /*readonly*/ IKernel kernel;  // Every file manager belongs to 1 kernel
    public FileManager(IKernel kernel) { this.kernel = kernel; /* etc. */ }
}

这种设计的问题是,只要FileManager尝试在其构造函数内部执行任何内容(它可能合理地需要),它就会在潜在的子类实例上调用一个虚方法,该实例的构造函数尚未被调用.

在你可以定义真正的构造函数(而不是初始化程序,如C#/ Java)的语言中不会出现这个问题,因为在它们的构造函数被调用之前,子类甚至都不存在……但是在这里,会出现这个问题.

那么什么是最佳/适当的设计/实践,以确保不会发生这种情况?

编辑:

我不一定说我需要循环引用,但事实是内核和FileManager都相互依赖.如果您有关于如何在不使用循环引用的情况下缓解此问题的建议,那么这也很棒!

解决方法

就个人而言,我不喜欢循环引用.但是如果你决定离开它们,你可能会增加一些懒惰:
interface IKernel
{
    // Useful members,etc.
}

class Kernel : IKernel
{
    private readonly Lazy<FileManager> fileManager;  // Every kernel has 1 file manager
    public Kernel() { this.fileManager = new Lazy<FileManager>(() => new FileManager(this)); /* etc. */ }

    // implements the interface; members are overridable
}

class FileManager
{
    private /*readonly*/ IKernel kernel;  // Every file manager belongs to 1 kernel
    public FileManager(IKernel kernel) { this.kernel = kernel; /* etc. */ }
}

这里的懒惰让我们确保在查询FileManager实例时将完全初始化IKernel实现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读