Frage

Ich bin derzeit eine weit verbreitete Klasse zu verändern, wie viel der teuren Initialisierung aus der Klasse Konstruktor in Faulen Initialized Eigenschaften zu bewegen. Unten ist ein Beispiel (in c #):

Bevor:

public class ClassA
{
    public readonly ClassB B;

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

Nach:

public class ClassA
{
    private ClassB _b;

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

            return _b;
        }
    }
}

Es gibt eine faire einige dieser Eigenschaften in der Klasse I zu verändern bin, und einige sind nicht in bestimmten Kontexten (daher der Laziness) verwendet, aber wenn sie verwendet werden, werden sie wahrscheinlich immer wieder aufgerufen werden.

Leider sind die Eigenschaften oft auch innerhalb der Klasse verwendet. Das heißt, es ist ein Potenzial für die private Variable (_b) direkt durch ein Verfahren verwendet werden, ohne dass es initialisiert wird.

Gibt es eine Möglichkeit nur die öffentliche Eigenschaft (B) zur Verfügung innerhalb der Klasse zu machen, oder auch eine alternative Methode mit dem gleichen initialisiert-wenn-notwendig?

Dies ist reposted von Programmierern (nicht subjektiv genug scheinbar): https://softwareengineering.stackexchange.com/questions/34270/best- Methoden-for-faul-Initialisierung-mit-Eigenschaften

War es hilfreich?

Lösung

Sie könnten betrachten die faulen Eigenschaften in einer Basisklasse drängen den direkten Zugriff auf die Träger Variable zu vermeiden. Nicht ideal ich kenne. Ich habe immer gedacht, das war etwas fehlt in C # das heißt die direkte Unterstützung für faule Eigenschaften.

Andere Tipps

Nun, meine empfohlene Lösung wäre, um Ihre Mitarbeiter zu sagen, das Eigentum zu verwenden, nicht das Feld. Aber man könnte es idiotensicher bis zu einem gewissen Grad wie folgt aus:

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

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

Jetzt ist es ziemlich schwer vermasseln.

@chibacity geschrieben (und später) gelöscht [und später wiederhergestellt: P] eine alternative Option eine abstrakte Basisklasse verwenden. Es ist zwar nicht ideal in Bezug auf die Code-Distribution sein kann macht es eine schöne Verkapselung bieten eine Menge Code Unordnung machen für eine sauberere und prägnanter KlasseA entfernen. Zum Beispiel könnten Sie die Techniken kombiniert betrachten, beide Ziele zu erreichen:

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

Auf den ersten Blick scheint es so mehr ist langatmig, aber wenn man bedenkt, dass KlasseA welche die Klasse ist, dass Sie in und mit arbeiten würde, dies nun bedeutet, dass alle Ihre Referenzen durch die gleiche Eigenschaft gehen - es gibt kein Fremd unnötige Feld mögliche Verwirrung zu verursachen, gibt es keine Immobilie zu Referenz _b Umgehung nicht erforderlich, direkt und es ist Ihre Mitarbeiter zu sagen, welche zu verwenden ... es gibt nur einen.

Nicht sagen, dies ist der richtige Weg, dies zu tun oder dass dies ein Muster, das sollte oder nicht folgen, ich den Hinweis auf nur die Vorteile, was @chibacity vorgeschlagen, die sonst unbemerkt bleiben können.

Es wäre schön, wenn Sie implizite faul geladene Eigenschaften haben könnten, ohne zum Beispiel zu B.Wert ... beziehen zu müssen:

[Lazy]
public ClassB B { get; }

oder für Objekte ohne parameterlos Bauer

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

oder vielleicht als @chibacity in einem Kommentar vorgeschlagen

public ClassB B { lazyget; }

oder

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

Ach, ich glaube nicht, dass diese sind derzeit verfügbare Lösungen in irgendeiner Form ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top