Pregunta

Actualmente estoy alterando una clase ampliamente usada para mover la mayor cantidad de inicialización costoso desde el constructor de la clase en propiedades Lazy inicializado. A continuación se muestra un ejemplo (en C #):

Antes:

public class ClassA
{
    public readonly ClassB B;

    public void ClassA()
    {
        B = new ClassB();
    }
}

Después de:

public class ClassA
{
    private ClassB _b;

    public ClassB B
    {
        get
        {
            if (_b == null)
            {
                _b = new ClassB();
            }

            return _b;
        }
    }
}

Hay un poco más razonable de estas propiedades de la clase que estoy alterando, y algunos no se utilizan en ciertos contextos (de ahí la Pereza), pero si se utilizan son propensos a ser llamado en repetidas ocasiones.

Por desgracia, las propiedades son a menudo también se utiliza dentro de la clase. Esto significa que hay un potencial para la variable privada (_b) a ser utilizado por un método sin que se inicializa.

¿Hay una manera de hacer sólo la propiedad pública (B) disponibles dentro de la clase, o incluso un método alternativo con el mismo, cuando sea necesario-inicializado?

Esta es publicado en de programadores (no hay suficiente subjetiva aparentemente): https://softwareengineering.stackexchange.com/questions/34270/best- métodos-para-lazy-inicialización-con-propiedades

¿Fue útil?

Solución

Se podría considerar que empuja las propiedades de descanso en una clase base para evitar el acceso directo a la variable de respaldo. No sé yo ideal. Siempre he pensado que esto era algo que falta en C # apoyo directo es decir, para las propiedades perezosas.

Otros consejos

Bueno, mi solución recomendada sería decirle a su compañero de trabajo a utilizar la propiedad, no el campo. Pero se podría a prueba de idiotas que hasta cierto punto como esto:

public class ClassA
{
    private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());

    public ClassB B
    {
        get
        {
            return _b.Value;
        }
    }
}

Ahora que es bastante difícil arruinas.

Publicado @chibacity (y posteriormente) suprime [y más tarde revirtió la eliminación: P] una opción alternativa que utiliza una clase base abstracta. Si bien puede no ser ideal en términos de distribución de código que proporciona un buen encapsulación eliminación de una gran cantidad de código toma el desorden para un limpiador y más sucinta claseA. Por ejemplo, usted podría considerar la combinación de las técnicas para lograr ambos objetivos:

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; } }
}

A primera vista, parece que este es aliento más largo, pero si tenemos en cuenta que es Clase A, que es la clase que estaría trabajando en y con, esto significa ahora que todas sus referencias están pasando por la misma propiedad - no hay no extraña campo innecesaria causando confusión potencial, no hay sin pasar por el alojamiento hasta _b referencia directa y no hay necesidad de decirle a su compañero de trabajo cuál utilizar ... sólo hay una.

No digo que esta es la forma correcta de hacer esto o que este es un patrón que debe o no debe ser seguido, sólo estoy señalando las ventajas de lo que sugirió @chibacity que puede pasar desapercibido lo contrario.

Sería bueno si pudiera tener propiedades cargadas perezosos implícitos sin tener que referirse a B.Value ... por ejemplo:

[Lazy]
public ClassB B { get; }

o para objetos sin constructores sin parámetros

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

o tal vez como @chibacity se sugiere en un comentario

public ClassB B { lazyget; }

o

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

Por desgracia, no creo que ninguna de estas son soluciones disponibles actualmente en cualquier forma ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top