Methods for lazy initialization with properties

I am currently modifying a widely used class to move most of the expensive initialization from the class constructor to the 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 just a few of these properties in the class I'm modifying, and some of them are not used in certain contexts (hence Laziness), but if they are used, they are likely to be called again.

Unfortunately, properties are often also used inside a class. This means that for the private variable (_b), you can use the method directly without initialization.

Is there a way to make only the public property (B) available inside the class, or even an alternative method with the same initialized if necessary?

This is sent from programmers (not subjectively enough): https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties

+8
c # lazy-initialization recommendation-engine
source share
3 answers

You might consider dragging lazy properties into the base class to avoid direct access to the fallback variable. I don’t know what I know. I always thought that this was something missing in C #, i.e. Direct support for lazy properties.

+6
source share

Well, my recommended solution was to tell your colleague to use the property, not the field. But you could idiotically prove this to some extent:

 public class ClassA { private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB()); public ClassB B { get { return _b.Value; } } } 

Now it's pretty hard to mess up.

+16
source share

@chibacity is published (and subsequently) deleted [and later restored: P] an alternative using an abstract base class. Although it may not be ideal in terms of code distribution, it does provide excellent encapsulation by removing a lot of code cloning for a cleaner and more concise class. For example, you might consider combining methods to achieve both goals:

 public class ClassB { /* Class to be lazily instantiated */ } public abstract class BaseA { private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB()); public virtual ClassB B { get { return _b.Value; } } } public class ClassA : BaseA { public override ClassB B { get { return base.B; } } } 

At first glance, it seems that this is a longer wind, but if you think that ClassA, which is the class in which you will work and with which, it means that all your links go through the same property - there is no extraneous an unnecessary field causing potential confusion, there is no going around the property for the _b link directly, and there is no need to tell your colleague who should use ... there is only one.

Not to say that this is the right way to do this or that, it is a template that should or should not be respected, I just point out the advantages of what @chibacity suggested, which might otherwise go unnoticed.

It would be nice if you had implicit lazy loaded properties without reference to B.Value ... for example:

 [Lazy] public ClassB B { get; } 

or for objects without constructors without parameters

 [Lazy(() => new ClassB("Hello", "World"))] public ClassB B { get; } 

or maybe like @chibacity suggested in the comment

 public ClassB B { lazyget; } 

or

 public ClassB B { lazyget : new ClassB(); } 

Alas, I do not think that any of them are currently available in any form ...

+3
source share

Source: https://habr.com/ru/post/650763/


All Articles