Frage

erhalte ich eine Warnung, wenn ich einige Code durch Visual Studio-Code-Analyse-Dienstprogramm ausführen, die ich bin mir nicht sicher, wie zu lösen. Vielleicht hier jemand über ein ähnliches Problem kommen, beschlossen sie, und ist bereit, ihre Einsicht zu teilen.

Ich programmiere eine benutzerdefinierte gemaltes Zelle in einer Datagridview-Kontrolle verwendet. Der Code ähnelt:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }

Es erzeugt die folgende Warnung:

CA2000: Microsoft.Reliability: In der Methode 'DataGridViewMyCustomColumn.DataGridViewMyCustomColumn ()' Aufruf System.IDisposable.Dispose auf Objekt 'neues DataGridViewMyCustomCell ()', bevor alle Verweise darauf sind out of scope <. / p>

Ich verstehe es warnt mich DataGridViewMyCustomCell (oder eine Klasse, die es erbt von) implementiert die IDisposable-Schnittstelle und die Methode Dispose () sollte alle Ressourcen aufgerufen werden durch DataGridViewMyCustomCell beansprucht aufzuräumen, wenn es nicht mehr.

Die Beispiele, die ich im Internet gesehen habe, die Lebensdauer des Objekts unter Verwendung eines Block Rahmen vorschlagen und haben das System automatisch entsorgt, sondern Basis wird nicht erkannt, wenn sie in den Körper des Konstruktor bewegt, so kann ich nicht Brief mit Block um es ..., die ich bin nicht sicher, würde ich auf jeden Fall tun will, da würde nicht, dass später in der Basisklasse anweisen, die Laufzeit um das Objekt zu befreien, die noch verwendet werden könnten?

Meine Frage ist also der Code in Ordnung wie? Oder wie könnte es Refactoring werden, um die Warnung zu lösen? Ich will nicht, um die Warnung zu unterdrücken, wenn es wirklich angemessen ist, dies zu tun.

War es hilfreich?

Lösung

Wenn Sie mit Visual Studio 2010 wird dann CA2000 vollständig gebrochen. Es kann auch in anderen Versionen von FxCop (auch bekannt als Code-Analyse) gebrochen werden, aber VS2010 ist die einzige, die ich für bürgen. Unsere Code-Basis wird geben CA2000 Warnungen für Code wie folgt ...

internal static class ConnectionManager 
{
    public static SqlConnection CreateConnection()
    {
         return new SqlConnection("our connection string");
    }
}

... darauf hinweist, dass die Verbindung nicht angeordnet wird, bevor es in dem Verfahren des Umfangs erlischt. Nun, ja, das ist wahr, aber es ist nicht außerhalb des Bereichs für die Anwendung , wie es einen Anrufer zurückgegeben wird -, dass der ganze Sinn des Verfahrens ist! In gleicher Weise wird Ihr Konstruktorargument geht nicht von Umfang, sondern auf die Basisklasse wird übergeben, so dass es ein Fehlalarm von der Regel ist eher als ein tatsächliches Problem.

Dies war früher eine nützliche Regel sein, aber jetzt alle können Sie wirklich tun es deaktivieren, bis sie es zu beheben. Welches ist bedauerlich, weil die (wenigen) tatsächlich positive Ergebnisse sind Dinge, die behoben werden sollten.

Andere Tipps

Es gibt keine sichere und elegante Weise eine verkettete Konstruktor hat ein neues IDisposable Objekt an der Basis Konstruktor übergeben, da, wie Sie merken es nicht möglich ist, die gekettet Konstruktoraufruf in jeder Art von try finally Block zu wickeln. Es ist ein Ansatz, der sicher ist, aber es ist kaum elegant: ein Dienstprogramm Methode so etwas wie definieren:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR
{ 
  dest = value; return value;
}

Haben Sie den Konstruktor Blick etwas wie:

protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
   base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell()))
{
}

-Code, die ein neues Objekt benötigt würde dann eine öffentliche statische Factory-Methode aufrufen müssen, die den entsprechenden Konstruktor innerhalb eines try / finally Block, dessen würde null aus Hauptleitung cleaner einfach anrufen würde, bevor es fertig, und dessen finally Block würde Dispose nennen auf cleaner wenn es nicht null. Vorausgesetzt, dass jede Unterklasse Verfahren eine ähnliche Fabrik definiert, wird dieser Ansatz sicher, dass das neue IDisposable Objekt erhalten angeordnet, auch wenn eine Ausnahme zwischen der Zeit kommt es erstellt wird und die Zeit, die Einkapselung Objekt Client-Code ausgesetzt ist. Das Muster ist hässlich, aber ich bin nicht sicher, ob irgendein netten andere Muster Korrektheit sicherstellen.

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