Warum hebt FxCop die Fehler „Typen, die Wegwerf-Felder besitzen sollte Einweg sein“ ohne Einweg-Felder auf einer Klasse?

StackOverflow https://stackoverflow.com/questions/1219086

  •  10-07-2019
  •  | 
  •  

Frage

Ich habe ein LINQ-Objekt mit einer zusätzlichen Methode hinzugefügt. Die Klasse hat keine Einweg-Eigenschaften oder Methoden, aber FxCop hebt den Fehler „Typen, die Wegwerf-Felder besitzen Einweg sein sollte“ und Referenzierung diese Klasse.

Ich habe den Code so weit reduziert und erhalte immer noch den Fehler:

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from wiki in context.Wikis
                from pageTag in context.VirtualWikiPageTags
                select new {};

            return null;
        }
    }
}

Wenn ich jedoch eine der beiden von Klauseln zu entfernen, stoppt FxCop den Fehler geben:

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from pageTag in context.VirtualWikiPageTags
                select new {};

            return null;
        }
    }
}

oder

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from wiki in context.Wikis
                select new {};

            return null;
        }
    }
}

PagePermissionSet ist nicht Einweg.

Ist das ein falsch positives Ergebnis? Oder ist der LINQ-Code irgendwie ein Wegwerf-Feld auf der Klasse zu erzeugen? Wenn es nicht um einen Fehlalarm handelt, FxCop empfiehlt, dass ich den IDisposable-Schnittstelle implementieren, aber was würde ich in der Dispose-Methode zu tun?

EDIT: Der vollständige FxCop Fehler ist:

  

"Implementieren Sie IDisposable auf‚Wikiseite‘, weil es   schafft Mitglieder der folgenden IDisposable-Typen:   'WikiTomeDataContext'. Wenn ‚WikiSeite‘ hat zuvor   geliefert, das Hinzufügen neuer Mitglieder, die IDisposable implementieren   auf diese Art wird eine Bruch Änderung bestehender betrachtet   Verbraucher. "

Edit 2: Dies ist der demontierten Code, der den Fehler auslöst:

public PagePermissionSet GetUserPermissions(Guid? userId)
{
    using (WikiTomeDataContext context = new WikiTomeDataContext())
    {
        ParameterExpression CS$0$0001;
        ParameterExpression CS$0$0003;
        var permissions = context.Wikis.SelectMany(Expression.Lambda<Func<Wiki, IEnumerable<VirtualWikiPageTag>>>(Expression.Property(Expression.Constant(context), (MethodInfo) methodof(WikiTomeDataContext.get_VirtualWikiPageTags)), new ParameterExpression[] { CS$0$0001 = Expression.Parameter(typeof(Wiki), "wiki") }), Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType8..ctor), new Expression[0], new MethodInfo[0]), new ParameterExpression[] { CS$0$0001 = Expression.Parameter(typeof(Wiki), "wiki"), CS$0$0003 = Expression.Parameter(typeof(VirtualWikiPageTag), "pageTag") }));
        return null;
    }
}

Edit 3: Es erscheint eine Verschluss Klasse, um einen Verweis auf die Datacontext enthält. Hier ist der demontierten Code:

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    // Fields
    public WikiTomeDataContext context;

    // Methods
    public <>c__DisplayClass1();
}
War es hilfreich?

Lösung

Meine Vermutung ist, dass der beide From Klauseln einen Anruf erzeugt mit einem Verschluss auf dem Datenkontext SelectMany. Die Instanz des Verschlusses hat ein Feld mit dem Datacontext, die die FxCop Warnung verursacht. Dies ist kein Grund zur Sorge.

Es gibt nur eine Instanz der Datacontext, die Sie über die Verwendung von Block aufzuräumen. Da die Schließung dort keine Finalizerthread hat keine Leistung oder saftey Implikation hier in der FxCop-Warnung.

Andere Tipps

Ich habe bemerkt, dass dies eine partielle Klasse ist. Haben Sie die andere Implementierungsdatei für die Klasse überprüft und sehen, ob es ein IDisposable Mitglied hat, der nicht vorgesehen ist?

Ich glaube nicht, das erzeugte Schließung Schuld ist hier. Verschlüsse werden mit bestimmten Attributen erzeugt, die FxCop verursachen sollten Warnungen wie diese zu ignorieren.

Bearbeiten

Weitere Untersuchungen durch den OP zeigten dies ein Problem mit einem IDisposable Feld sein wird, in eine Schließung aufgehoben.

Leider gibt es nicht viel Sie dagegen tun können. Es gibt keine Möglichkeit, die Schließung implementieren IDisposable zu machen. Ereignis, wenn Sie könnten es gibt keine Möglichkeit IDisposable über die Schließung Instanz anzurufen.

Der beste Weg, um dieses Problem zu nähern ist der Code so zu umschreiben, dass ein Einweg-Wert nicht in der Schließung gefangen genommen. Einweg-Felder sollten immer entsorgt werden, wenn sie fertig sind und es in einem Verschluss Erfassung verhindert, dass Sie dies zu tun.

Wenn Sie eine LINQ-Abfrage aus dem Verfahren zurückkehrt, werden die Verbraucher über die Ergebnisse iterieren foreach verwendet wird.

Wenn ein Verbraucher eine foreach-Schleife beendet ist, ruft es intern auf der IEnumerable Quelle verfügen (in diesem Fall Ihre LINQ-Abfrage). Dadurch wird die WikiTomeDataContext entsorgen.

Wenn jedoch ein Verbraucher einen Aufruf der Methode der Rückkehr einer LINQ-Abfrage gemacht, aber nie über die Ergebnisse iteriert, so scheint es, dass enumerable würde nie entsorgt werden (das heißt, bis der Garbage Collector das Objekt gereinigt). Dies würde zu Ihrer WikiTomeDataContext erst Garbage Collection angeordnet ist.

Eine Möglichkeit, Sie könnten in der Lage sein, um dieses Problem zu bekommen, ist durch .ToArray auf dem Ergebnis Ihrer LINQ-Abfrage anrufen, wählen Sie auf Ihrem Kontext verfügt, dann das Array zurück.

Der Code, der den Fehler verursacht verwendet WikiDataContext.

Ihre zwei Beispiele, die verwendet werden WikiTomeDataContext keinen Fehler geben.

Vielleicht gibt es einige Unterschiede zwischen diesen beiden, die den Fehler verursacht.

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