使用属性进行延迟初始化的方法
我目前正在更改一个广泛使用的类,以将尽可能多的昂贵初始化从类构造函数转移到延迟初始化属性中。下面是一个示例(在 C# 中):
之前:
public class ClassA
{
public readonly ClassB B;
public void ClassA()
{
B = new ClassB();
}
}
之后:
public class ClassA
{
private ClassB _b;
public ClassB B
{
get
{
if (_b == null)
{
_b = new ClassB();
}
return _b;
}
}
}
我正在更改的类中还有相当多的这些属性,其中一些在某些上下文中没有使用(因此是惰性),但如果使用它们,它们就会可能会被重复调用。
不幸的是,这些属性也经常在类内部使用。这意味着私有变量 (_b) 有可能在不初始化的情况下直接被方法使用。
有没有办法只让公共属性(B)在类中可用,或者甚至是具有相同的需要时初始化的替代方法?
这是从程序员转发的(显然不够主观): https://softwareengineering.stackexchange.com/questions/34270/best-带属性的延迟初始化方法
I'm currently altering a widely used class to move as much of the expensive initialization from the class constructor into Lazy Initialized properties. Below is an example (in c#):
Before:
public class ClassA
{
public readonly ClassB B;
public void ClassA()
{
B = new ClassB();
}
}
After:
public class ClassA
{
private ClassB _b;
public ClassB B
{
get
{
if (_b == null)
{
_b = new ClassB();
}
return _b;
}
}
}
There are a fair few more of these properties in the class I'm altering, and some are not used in certain contexts (hence the Laziness), but if they are used they're likely to be called repeatedly.
Unfortunately, the properties are often also used inside the class. This means there is a potential for the private variable (_b) to be used directly by a method without it being initialized.
Is there a way to make only the public property (B) available inside the class, or even an alternative method with the same initialized-when-needed?
This is reposted from Programmers (not subjective enough apparently):
https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,我推荐的解决方案是告诉你的同事使用该财产,而不是该字段。但你可以在某种程度上防止白痴这样做:
现在很难搞砸了。
Well, my recommended solution would be to tell your coworker to use the property, not the field. But you could idiot-proof it to some degree like this:
Now it's pretty hard to screw up.
您可以考虑将惰性属性推入基类中,以避免直接访问支持变量。我知道并不理想。我一直认为这是 C# 所缺乏的东西,即对惰性属性的直接支持。
You could consider pushing the lazy properties into a base class to avoid direct access to the backing variable. Not ideal I know. I've always thought this was something lacking in C# i.e. direct support for lazy properties.
@chibacity 发布(随后)删除了[后来又取消删除:P]使用抽象基类的替代选项。虽然它在代码分发方面可能并不理想,但它确实提供了一个很好的封装,消除了大量混乱的代码,从而形成更干净、更简洁的 ClassA。例如,您可以考虑结合使用这些技术来实现这两个目标:
乍一看,这似乎比较冗长,但是当您考虑 ClassA 是您将在其中工作并使用的类时,这现在意味着所有您的引用将通过相同的属性 - 没有多余的不必要字段导致潜在的混乱,没有绕过该属性直接引用 _b 并且无需告诉您的同事使用哪个...只有一个。
我并不是说这是正确的方法,也不是说这是应该遵循或不应该遵循的模式,我只是指出 @chibacity 建议的优点,否则可能会被忽视。
如果您可以拥有隐式延迟加载属性而不必引用 B.Value... 例如:
或者对于没有无参数构造函数的对象
,或者可能像@chibacity 在评论中建议的那样
,或者
唉,我不认为有任何其中目前有任何形式的可用解决方案......
@chibacity posted (and subsequently) deleted [and later undeleted :P] an alternative option using an abstract base class. While it may not be ideal in terms of code distribution it does provide a nice encapsulation removing a lot of code clutter making for a cleaner and more succinct ClassA. For instance, you could consider combining the techniques to achieve both goals:
At first glance, it seems like this is more long winded, but when you consider that ClassA which is the class you would be working in and with, this now means that all your references are going through the same property - there is no extraneous unnecessary field causing potential confusion, there's no bypassing the property to reference _b directly and there's no need to tell your coworker which to use... there's only one.
Not saying this is the right way to do this or that this is a pattern that should or shouldn't be followed, I'm just pointing out the advantages of what @chibacity suggested that may otherwise go unnoticed.
It would be nice if you could have implicit lazy loaded properties without having to refer to B.Value... for instance:
or for objects without parameterless constructors
or perhaps as @chibacity suggested in a comment
or
Alas, I don't think any of these are currently available solutions in any form...