延迟初始化好不好?

问题描述 投票:0回答:2

我刚刚发现了一个由同事创建的名为HmeRevisionTracker的类。它仅包含简单对象的List <>。 CSimCharge,这个项目中最重要的类之一,包含一个HmeRevisionTracker对象,它是这样声明的公共属性:

    public HmeRevisionTracker RevisionTracker { get; private set; }

没有理由不能在CSimCharge构造函数中创建对象,因为HmeRevisionTracker是完全硬编码的,没有任何改变。但是,它不是在那里创建的。而是将其初始化为jull。除非使用,否则不会创建它:

    void CheckForHeatModelRevision()
    {
        // Find the next revision that needs to be performed
        if (RevisionTracker == null && UseModel)
            RevisionTracker = new HmeRevisionTracker(ActualBase.CoilLoad, ActualBase.IsHeating);

据我所知,这没有问题,但我很好奇。此代码有我不知道的某些缺点吗?

实施对于这个问题不重要,但是这里还是有一些问题:

public class HmeRevisionRule
{
    public double CheckPointThreshold { get; private set; }
    public bool RevisionNeeded { get; set; }
    public bool IsHeatingRule { get; private set; }
    public bool IsCoolingRule { get { return !IsHeatingRule; } }

    public HmeRevisionRule(double threshold, bool isHeatingRule)
    {
        CheckPointThreshold = threshold;
        RevisionNeeded = true;
        IsHeatingRule = isHeatingRule;
    }
}

public class HmeRevisionTracker
{
    public LinkedList<HmeRevisionRule> CheckPointRules { get; private set; }

    public HmeRevisionTracker(CSimCoilGroup coilLoad, bool isHeating)
    {
        CheckPointRules = new LinkedList<HmeRevisionRule>();

        // Default Heating & Cooling Check Points
        CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, true));
        CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, true));
        CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, true));
        CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, true));
        CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, true));

        CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, false));
        CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, false));
        CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, false));
        CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, false));
        CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, false));

        Initialize(coilLoad, isHeating);
    }

初始化会根据充电状态设置个别规则。该类的其他方法检索所需的规则或更改规则的设置。

c# initialization lazy-initialization
2个回答
1
投票

这称为惰性初始化,是提高性能的一种常见做法。将其标记为“好”或“坏”是主观的,并且取决于使用它的上下文。

在您的示例中,HmeRevisionTracker类的初始化可能很昂贵,因此仅应在实际需要时才进行。当RevisionTrackernull时,其他代码可能会依赖其他含义(即,它可能表示尚未调用其他方法,描述了一些内部状态)。

[有一篇关于延迟初始化主题here的文章,其中部分指出:

延迟初始化主要用于提高性能,避免浪费的计算并减少程序内存需求。最常见的情况是:

  • 当您创建的对象创建起来很昂贵时,程序可能不会使用它。
  • 当您有一个创建成本很高的对象,并且想要将其创建推迟到其他昂贵的操作完成之后。

如本文所述,.NET 4.0中引入了一个Lazy<T>类,该类可用于使其更加有意,并可能减少代码行。


最后,关于您的陈述:

没有理由不能在CSimCharge构造函数中创建对象

Microsoft的Lazy<T>状态:

✓DO构造函数中的最少工作。除了捕获构造函数参数外,构造函数不应做太多工作。任何其他处理的成本都应延迟到需要时才进行。

(感谢@madreflection这部分!)


0
投票

这是我的个人观点,当构造函数完成后,该对象应该“可以使用”:因此Member Design Guidelines on Constructor Design对象应该在构造函数中构建。今天,执行此操作所需的几毫微秒的时间无关紧要。但是,意外的运行时错误和由此导致的(生产?)应用程序崩溃可能会花费很多钱。即使没有使用它们,也要在构造函数中构造所有必需的东西,然后将它们拆解到析构函数中。

如果属性为List并且可能实际上未使用,请明确将其初始化为private。最重要的一点是该值不是unpredictable。(“它不是零,但没有任何好处。”)

© www.soinside.com 2019 - 2024. All rights reserved.