我刚刚发现了一个由同事创建的名为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);
}
初始化会根据充电状态设置个别规则。该类的其他方法检索所需的规则或更改规则的设置。
这称为惰性初始化,是提高性能的一种常见做法。将其标记为“好”或“坏”是主观的,并且取决于使用它的上下文。
在您的示例中,HmeRevisionTracker
类的初始化可能很昂贵,因此仅应在实际需要时才进行。当RevisionTracker
为null
时,其他代码可能会依赖其他含义(即,它可能表示尚未调用其他方法,描述了一些内部状态)。
[有一篇关于延迟初始化主题here的文章,其中部分指出:
延迟初始化主要用于提高性能,避免浪费的计算并减少程序内存需求。最常见的情况是:
- 当您创建的对象创建起来很昂贵时,程序可能不会使用它。
- 当您有一个创建成本很高的对象,并且想要将其创建推迟到其他昂贵的操作完成之后。
如本文所述,.NET 4.0中引入了一个Lazy<T>
类,该类可用于使其更加有意,并可能减少代码行。
最后,关于您的陈述:
没有理由不能在CSimCharge构造函数中创建对象
Microsoft的Lazy<T>
状态:
✓DO构造函数中的最少工作。除了捕获构造函数参数外,构造函数不应做太多工作。任何其他处理的成本都应延迟到需要时才进行。
(感谢@madreflection这部分!)
这是我的个人观点,当构造函数完成后,该对象应该“可以使用”:因此Member Design Guidelines on Constructor Design对象应该在构造函数中构建。今天,执行此操作所需的几毫微秒的时间无关紧要。但是,意外的运行时错误和由此导致的(生产?)应用程序崩溃可能会花费很多钱。即使没有使用它们,也要在构造函数中构造所有必需的东西,然后将它们拆解到析构函数中。
如果属性为List
并且可能实际上未使用,请明确将其初始化为private
。最重要的一点是该值不是unpredictable。(“它不是零,但没有任何好处。”)