2011-01-10 1 views
1

Gibt es eine Möglichkeit, eine using Anweisung zu schreiben, ohne die IDisposable sofort instanziieren?Verzögerte Instanziierung mit C# mit Hilfe der Anweisung

Zum Beispiel, wenn ich etwas tun musste, wie:

using (MyThing thing) 
{ 
    if (_config == null) 
    { 
     thing = new MyThing(); 
    } 
    else 
    { 
     thing = new MyThing(_config); 
    } 

    // do some stuff 

} // end of 'using' 

Gibt es eine akzeptierte Muster für Fälle wie diesen? Oder bin ich zurück zum Umgang mit dem IDisposable explizit nochmal?

+0

3 (fast) identische Antworten in weniger als einer Minute. Nett! : D – Rob

Antwort

4

Nun, in Ihrem Beispiel Sie tun instanziieren Sie das Einwegobjekt sofort - nur basierend auf einer Bedingung. Zum Beispiel könnten Sie verwenden:

using (MyThing thing = _config == null ? new MyThing() : new MyThing(_config)) 
{ 
    ... 
} 

allgemeiner zu sein, können Sie eine Methode verwenden:

using (MyThing thing = CreateThing(_config)) 
{ 
} 

Der schwierige Bit wäre, wenn der Zeitpunkt der Instanziierung von verschiedenen Bedingungen auf Basis verändert. Das wäre in der Tat schwieriger zu handhaben mit einer using Anweisung, würde aber auch vorschlagen, dass Sie versuchen sollten, Ihren Code umzuformatieren, um diese Anforderung zu vermeiden. Es wird nicht immer möglich sein, aber es ist einen Versuch wert. Eine andere Alternative ist es, das "Ding" in einem Wrapper zu kapseln, der das echte Einwegobjekt passend erzeugt und an dieses für die Entsorgung und alles andere delegiert, was Sie mit dem Typ machen können. Eine Delegation wie diese kann in manchen Situationen ein Schmerz sein, aber sie könnte angemessen sein - je nachdem, was Sie wirklich tun wollen.

+0

gründlich und informativ wie immer mein Herr, danke. – fearofawhackplanet

2
using (MyThing thing = _config == null ? new MyThing() : new MyThing(_config)) 
{ 
    // .... 

} 
1

Sie könnten tun:

if (_config == null) 
{ 
    thing = new MyThing(); 
} 
else 
{ 
    thing = new MyThing(_config); 
} 

using (thing) 
{ 

    // do some stuff 
} 
1

Ich denke, die meisten vernünftige Lösung ist die Entscheidung, was mit der Config in den Mything Konstruktor zu bewegen. Auf diese Weise können Sie die Verwendung der Klasse wie folgt vereinfachen:

using (MyThing thing = new MyThing(_config)) 
{ 

} 

class MyThing { 
    public MyThing() { 
    //default constructor 
    } 

    public MyThing(Config config) :this() { 
    if (config == null) 
    { 
     //do nothing, default constructor did all the work already 
    } 
    else 
    { 
     //do additional stuff with config 
    } 
    } 
}