Was ist der richtige Weg, um teilweise erstellte Objekte in einer Fabrikmethode freizugeben?C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Was ist der richtige Weg, um teilweise erstellte Objekte in einer Fabrikmethode freizugeben?

Post by Anonymous »

Ich habe eine Klasse myClass , die Instanzen eines , b und c für die Initialisierung erstellt werden müssen.
Alle drei Klassen erben idisposable . Ich habe keinen Zugriff auf den Quellcode eines , b und c , aber ihre Konstruktoren können eine Ausnahme für bestimmte Parameterkombinationen ausgeben. In einem Konstruktor ist eine schlechte Praxis, weil sie die Klasse in einem inkonsistenten Zustand im Gedächtnis (invariante Verletzung) belassen kann. Anstatt einen direkten Konstruktor zu verwenden, verwende ich eine Werksmethode myclass.create () , mit der ein , b und c initialisiert wird. Die Funktion create löst eine Ausnahme aus, wenn eine von einem , b und c eine Ausnahme ausgelöst hat. Ich weiß, wenn ich B nicht erstelle, sollte ich mindestens A kostenlos freigeben und die Ausnahme erheben. Ich weiß auch, dass ich, wenn ich die Klasse C nicht erstelle, zumindest frei erstellt habe, die zuvor eine und b erstellt und dann die Ausnahme in der Funktion create aufnehmen.
Bitte sagen Sie mir, gibt es ein gutes Muster- oder Code -Beispiel: Wie kann ich zuvor initialisierte Teile aufräumen, wenn ich die Klassenmyclass < /code>?
nicht erstelle sind mehr als drei Teile? Ich denke darüber nach, Stack Stack zum Aufräumen von Teilen zu verwenden.

Code: Select all

class A: IDisposable
{
private readonly int p_value;

public A(int value)
{
ArgumentOutOfRangeException.ThrowIfNegative(value);
p_value = value;
}

public void Print()
{
Console.WriteLine($"Value is: {p_value}");
}

public void Dispose()
{
Console.WriteLine("A disposed");
}
}

class B : IDisposable
{
private readonly int p_value;

public B(int value)
{
ArgumentOutOfRangeException.ThrowIfLessThan(value, 10);
p_value = value;
}

public void Print()
{
Console.WriteLine($"Value is: {p_value}");
}

public void Dispose()
{
Console.WriteLine("B disposed");
}
}

class C : IDisposable
{
private readonly int p_value;

public C(int value)
{
ArgumentOutOfRangeException.ThrowIfLessThan(value, 20);
p_value = value;
}

public void Print()
{
Console.WriteLine($"Value is: {p_value}");
}

public void Dispose()
{
Console.WriteLine("C disposed");
}
}

class MyClass: IDisposable
{
private readonly A a;
private readonly B b;
private readonly C c;
private bool disposedValue;

protected MyClass(A _a, B _b, C _c) { a = _a; b = _b; c = _c;}

public MyClass Create(int _value)
{
// Maybe throw error
A a = new A(_value);

// Maybe throw error
// Need free A
B b = new B(_value);

// Maybe throw error
// Need free A
// Need free B
C c = new C(_value);

return new (a, b, c);
}

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
}

a.Dispose();
b.Dispose();
c.Dispose();

disposedValue = true;
}
}

~MyClass()
{
Dispose(disposing: false);
}

public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post