Laden...

Reflection...

Erstellt von norman_timo vor 19 Jahren Letzter Beitrag vor 19 Jahren 2.093 Views
norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 19 Jahren
Reflection...

Hallo!

Nachdem ich einige mal scharf kritisiert worden bin, weil ich falsche Antworten gegeben hatte, konzentriere ich mich auf das (ernsthafte) Fragestellen:

Ich möchte gerne via Reflection auf eine Assembly-dll zugreifen, das hab ich auch hinbekommen und funktioniert.

Aber an einer bestimmten Stelle möchte ich es dem User erlauben via OpenFileDialog eine andere .dll Datei auszuwählen (oder die selbe aktualisieren).

Mein Code wird hier ohne Probleme ausgeführt, aber er übernimmt nicht die neue dll-Datei, er merkt sich irgendwie immer nur die alte.

Hier mal ein wenig Code:


namespace TestSender
{
	/// <summary>
	/// Summary description for MyReflection.
	/// </summary>
	public class MyReflection
	{

		private static System.Reflection.Assembly assembly;

	
		public MyReflection(string dllfilename)
		{

			assembly = System.Reflection.Assembly.LoadFrom(dllfilename); //***

			foreach(Type t in assembly.GetTypes())
			{
				if (t.IsClass)
				{
                                         // tu was bestimmtes damit
				}
			}

		}

	}
}

In meiner Hauptapplikation kreiere ich beim Start ein Objekt dieser Klasse, welches automatisch durch den Konstruktor die .dll Datei akzeptiert und verarbeitet.

Der Aufruf erfolgt so:


myReflection = new MyReflection(dllfilepath);

Bei einer dll-Aktualisierung wird derselbe Aufruf wiederholt, welches das alte Objekt zerstören sollte. (Tut er aber nicht!)

Aber jetzt der Hammer: ich habe versucht das Objekt 2x zu erstellen ungefähr so:


myReflection = new MyReflection(dllfilepath);
test = new MyReflection(anderer_dllfilepath); 

Und das 2. Objekt hat ebenfalls die "alte" Assembly Datei geladen, obwohl er ein neues Objekt erstelle, wieso ????

Mir geht das nicht in den Kopf, und vielleicht kann mir jemand helfen?

Norma-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

C
980 Beiträge seit 2003
vor 19 Jahren

Sollte zwar am Verhalten nichts ändern hier, aber gibt es einen speziellen Grund warum du die Assembly Variable statisch deklarierst?

norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 19 Jahren

Hallo!

Prinzipiell hat es keinen besonderen Grund, habe es auch ohne probiert, aber wie Du schon gesagt hast, das ändert nichts an dem ergebnis.

Habe es nur deshalb statisch angelegt, weil es auch nur einmal instanziiert und in der gesamten Klasse verfügbar sein soll.

Egal, aber das war das Problem leider nicht, danke trotzdem.

Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 19 Jahren

Hallo!

Vielleicht stelle ich die Frage mal etwas aus einer anderen Richtung:

Es gibt bei Windows.Forms auch die Möglichkeit ein Obect mit der Methode .Remove() definitif zu zerstören,

gibt es auch ein solcher Mechanismus, der C# dazu zwingt ein Objekt wirklich zu zerstören?

So wie bei C++ der Destruktor war, so etwas müsste doch in C# auch forcierbar sein, oder?

Vielleicht kann mir jetzt jemand helfen?

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

C
980 Beiträge seit 2003
vor 19 Jahren

Nein. Du kannst auch eine in eine ApplicationDomain geladene Assembly (wie du es machst) nicht mehr entladen, ausser du entlädst gleich die ganze Domain ...

(btw: sicher, dass mit Remove wirklich ein Objekt zerstört wird?)

333 Beiträge seit 2004
vor 19 Jahren

Von der Definition her wird ein Objekt dann zerstört, wenn es aus dem Speicher entfernt wird und das ist der Fall wenn der GarbageCollector aufräumt und keine Referenzen mehr auf ein Objekt findet. Erst dann wird auch der Destruktor aufgerufen, weshalb man über den genauen Zeitpunkt nie eine Aussage treffen kann. Daher hat man in .NET noch IDisposable erfunden. Mit der Dispose-Methode, die diese Schnittstellen beinhaltet, soll das Objekt seine Ressourcen wieder freigeben.

Und Controls.Remove, falls ihr das meint (?), entfernt ein Steuerelement nur vom entsprechendem Parent-Control. Das eigentliche Objekt bleibt erhalten, so daß es auch wieder hinzugefügt werden kann.

([bb]|[^b]{2})

N
4.644 Beiträge seit 2004
vor 19 Jahren

Mit GC.Collect() kann man die Garbage Collection erzwingen.

C
980 Beiträge seit 2003
vor 19 Jahren

Original von Noodles
Mit GC.Collect() kann man die Garbage Collection erzwingen.

Allerdings ist auch mit einem solchen Aufruf die Zerstörung noch nicht garantiert ...

C
65 Beiträge seit 2004
vor 19 Jahren

*spam* Wieso wollen eigentlich so viele Leute zwanghaft die CG mit der Hand machen?

/// <summary>
/// Signatur
/// </summary>

333 Beiträge seit 2004
vor 19 Jahren

GC.Collect() braucht und sollte man nicht von Hand aufrufen. Genauso dürfen dementsprechend die Klassen nicht so aufgebaut werden, so das der Destruktor lebensnotwendig ist. Dafür gibts eben Dispose. Über das using-Statement kann man ürbigens prima mit IDisposable-Klassen arbeiten. Der Code wird dadurch viel Übersichtlicher.

Beispiel ohne Using:


FileStream file = null;

try
{
	file = new FileStream(@"c:\myfile.dat", FileMode.Open);
	
	// ...
}
catch (IOException ex)
{
	// ...
}
finally
{
	if (file != null)
	{
		file.Close();
	}
}

Mit Using:


try
{
	using (FileStream file = new FileStream(@"c:\myfile.dat", FileMode.Open))
	{
		// ...
	}
}
catch (IOException ex)
{
	// ...
}

file.Close() wird automatisch aufgerufen, sobald der Using-Abschnitt verlassen wird, egal ob durch Exception, return oder auf normalem Wege. Usings funktionieren, soweit ich weiß, nur mit Klassen die IDisposable verwenden.

Noch zu GC.Collect(). Man sollte es nicht verwenden, weils inperformant ist. .NET kümmert sich selbst darum, wann es notwendig ist aufzuräumen. Und man braucht keine Bedenken haben, noch bevor angefangen wird auszulagern wird .NET einmal den GC laufen lassen 🙂

([bb]|[^b]{2})

C
65 Beiträge seit 2004
vor 19 Jahren

Original von NoOneKnows
Noch zu GC.Collect(). Man sollte es nicht verwenden, weils inperformant ist. .NET kümmert sich selbst darum, wann es notwendig ist aufzuräumen. Und man braucht keine Bedenken haben, noch bevor angefangen wird auszulagern wird .NET einmal den GC laufen lassen 🙂

Ja, eben. Genau deswegen verstehe ich es nicht. Aber es ist doch kaum so, dass alle, die unbedingt GC.Collect() machen wollen, ewig-gestrige C-Hacker sind? Ich tippe eher darauf, dass die GC in VB ziemlich miserabel war, in allen Versionen.

Allerdings rate ich trotzdem dazu, statt die GC "überlisten" zu versuchen, lieber mit ein paar Tools der GC in ihrer natürlichen Form bei der Arbeit zuzuschauen. Die ist nämlich verblüffend gut und effizient.

/// <summary>
/// Signatur
/// </summary>