Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Statische Codeanalyse mahnt CA1001 nicht an[=> korrekt]
Paschulke
myCSharp.de - Member



Dabei seit:
Beiträge: 63

Themenstarter:

Statische Codeanalyse mahnt CA1001 nicht an[=> korrekt]

beantworten | zitieren | melden

Hallo!

Ich bin irritiert über die statische Codanalyse:
Ich habe eine Klasse, die ein privates Feld besitzt, das IDisposable implementiert. Die Klasse selber besitzt zurzeit keine Dispose-Methode. Wenn ich CA1001 Types that own disposable fields should be disposable richtig verstehe, sollte die statische Codeanalyse nun diese Warnung bringen, wenn ich sie laufen lasse. Tut sie aber nicht. Lt. Codeanalyse ist mein Code in Ordnung.

Verstehe ich die Regel falsch? Oder gibt es Konstellationen in denen die statische Codeanalyse den Fehler nicht erkennt?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15703
Herkunft: BW

beantworten | zitieren | melden

Eine Klasse, die Methoden (hier Dispose) eines Interfaces (hier IDisposable) nicht implementieren, sind nicht kompilierbar.
Ich bezweifle also, dass der Code in Ordnung ist. Oder hat Deine Klasse nicht mal IDisposable? Ohne Code muss man immer raten...

Und was für ein Analysetool verwendest Du denn?
Der Code aus der MSDN funktioniert mit VS 2015 Code Analyse einwandfrei. Haste das denn selbst mal als Kontrolle ausgeführt??
Attachments
private Nachricht | Beiträge des Benutzers
Paschulke
myCSharp.de - Member



Dabei seit:
Beiträge: 63

Themenstarter:

beantworten | zitieren | melden

Grundsätzlich sieht mein Code schon so aus, wie Deiner. Ich habe mich etwas missverständlich ausgedrückt. Natürlich hat die Klasse, die IDisposable implementiert eine Dispose Methode. Ich meinte die Klasse, die ein Feld vom Typ des IDisposables besitzt, hat keine Dispose Methode...

Warnt die Codeanalyse nur, wenn das Feld innerhalb der Klasse erstellt wurde?
Ich fürchte das Problem liegt darin, dass ich einen IoC Container (Castle Windsor) verwende, der mir das zu disposende Objekt über Constructor Injection in meine Klasse hinein reicht. Der IoC Container erstellt dabei das Objekt. Ist er evtl. so schlau das Objekt bei Zeiten auch zu disposen, sodass ich mich gar nicht darum zu kümmern brauche? Dann wäre ja tatsächlich alles in Ordnung.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15703
Herkunft: BW

beantworten | zitieren | melden

Es warnt nur, wenn das Feld private ist.
Und Felder sollten immer private sein.

Wenn es also nicht innerhalb der Klasse erstellt wird, dann hast Du (offensichtlich?) kein privates Feld.
private Nachricht | Beiträge des Benutzers
Paschulke
myCSharp.de - Member



Dabei seit:
Beiträge: 63

Themenstarter:

beantworten | zitieren | melden

Das Feld ist private - sogar private readonly. Aber es wird aber außerhalb (vom IoC Container) erzeugt und über den Konstrukor in meine Klasse hineingereicht.

Ich hatte CA1001 so verstanden, dass die Codeanalyse (VS) immer warnt, wenn ein Feld disposable ist - unabhängig davon wer das Feld erstellt. Offensichtlich ist das nicht so. Das new ist entscheidend.

Dann muss ich mal in der Doku von Castle nachlesen, ob ich mich um das Dispose kümmern muss.

Vielen Dank, Abt für Deine Hilfe!
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 966

beantworten | zitieren | melden

Zitat von Paschulke
Dann muss ich mal in der Doku von Castle nachlesen, ob ich mich um das Dispose kümmern muss.
Welchen Lifestyle hat das Objekt?
private Nachricht | Beiträge des Benutzers
p!lle
myCSharp.de - Member

Avatar #avatar-3556.jpg


Dabei seit:
Beiträge: 1053

beantworten | zitieren | melden

Wenn du das Objekt - auf welchem Wege auch immer - von außen mit in die Klasse reichst, dann muss sich in meiner Welt die äußere Klasse um das Dispose kümmern, da nur sie weiß, wann das Objekt nicht mehr benötigt wird.

Beispiel:

public class MeineTolleSuperKlasse
{
	public MeineTolleSuperKlasse()
	{
		using (var stream = new FileStream(@"C:\test.txt", FileMode.Open))
		{
			stream.ReadByte();
			//Mache irgendwas

			var streamHelper = new StreamHelper(stream);
			streamHelper.Reset();

			stream.ReadByte();
			//Mache irgendwas
		}
	}
}

public class StreamHelper
{
	private readonly FileStream _stream;

	public StreamHelper(FileStream stream)
	{
		_stream = stream;
	}

	public void Reset()
	{
		_stream.Position = 0;
	}
}

Würde man jetzt hier erwarten, dass sich der StreamHelper um das Dispose kümmern soll?
MeineTolleSuperKlasse ist in deinem Fall der IoC-Container/Castle. =)

EDIT sagt noch, dass es auch Fälle gibt, in denen Objekte in IoC-Containern als SingleInstance erzeugt werden, er wäre katastrophal, wenn die zwischendurch einer abräumt (falls jemand nachfragt: mir ist aktuell kein praktischer Fall bekannt ).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von p!lle am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15703
Herkunft: BW

beantworten | zitieren | melden

Sobald etwas von Außen rein kommt, ist auch die Aussenstelle für das Disposen verantwortlich.
Die statische Codeanalyse ist in diesem Fall korrekt.
private Nachricht | Beiträge des Benutzers
Deaktiviertes Profil
myCSharp.de - Member



Dabei seit:
Beiträge: 996

beantworten | zitieren | melden

Ausnahmen von dieser Regel werden dann bei der Übergabe entsprechend vermerkt, so wie das z.B. bei StreamWriter mit dem übergebenen Stream erfolgt.
private Nachricht | Beiträge des Benutzers
Paschulke
myCSharp.de - Member



Dabei seit:
Beiträge: 63

Themenstarter:

beantworten | zitieren | melden

Zitat von witte
Welchen Lifestyle hat das Objekt?
Transient
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 966

beantworten | zitieren | melden

Bei transienten Objekten kann der Container nicht wissen wie lange du ihn brauchst. Schließlich könntest du auch mehrere Exemplare des Objektes anfordern wollen (z.B. immer wenn der Benutzer Speichern klickt willst du über das Uow Speichern, dieses verwerfen und ein neues anfordern).
Wenn die Klasse die das Objekt injiziert bekommt den Lifestyle Singleton hat wird das transiente Objekt die gesamte Zeit an diesem Singleton kleben bleiben, wird dann der Conatainer verworfen wird die Dispose-Methode aller Disposables des Containers aufgerufen. Man sollte sich überlegen ob es OK ist an ein Singleton ein Transientes Objekt zu binden.
Ansonsten ist es üblich transiente Objekte über eine Facility reinzugeben. Die hat dann eine Methode Destroy über die man das nicht mehr benötigte Objekt zurückgeben kann.
private Nachricht | Beiträge des Benutzers