Laden...

Forenbeiträge von Traumzauberbaum Ingesamt 512 Beiträge

27.04.2006 - 17:07 Uhr

Da die XmlNodes sowieso XmlElements sein müssten, kannst du doch die SetAttribute Methode von XmlElement benutzen. Oder seh ich das falsch? Wüsste zumindest nicht wozu man sonst Attribute hinzufügen soll außer Elementen...

XmlDocument XmlSource = new XmlDocument();
XmlSource.Load("sample.xml");

// Get the node to be modified.
XmlElement MyElement = (XmlElement)XmlSource.SelectSingleNode("/root/tag");

MyElement.SetAttribute( "hello", "world" );
27.04.2006 - 12:27 Uhr

Original von Robert G
Um es noch zu vervollständigen...
Falls generische Prüfungen mit der allseits beliebten Handbremse (Reflection 😁 ) nötig sind:

interface IA  
{}  
class A : IA  
{}  
Console.WriteLine("{0} implements {1}: {2}",  
                  typeof(A),  
                  typeof(IA),  
                  typeof(IA).IsAssignableFrom(typeof(A)));  

Also nicht mit IsSubClassOf prüfen...

Vielen Dank, das hätte ich jetzt gefragt nachdem die Eingangsfrage geklärt ist 😉

Im MSDN hatte ich irgendwo gelesen dass man IsSubClassOf nicht benutzen soll. IsAssignableFrom hab ich garnicht erst in Betracht gezogen 🙂

27.04.2006 - 11:53 Uhr

Original von herbivore
ganz schön polemisch. Ich habe nicht gesagt, dass ich alle Exceptions wegfangen will, ich habe nur gesagt, dass wenn ich Exceptions fange, (nahezu) immer alle Exceptions fange.

Und das ist eben eines der Probleme die ich mit der Antwort habe. Wenn nach "best practice" gefragt wird, solltest du nicht nur schreiben was du tust, sondern auch was du nicht tust. Und du hast eben nur geschrieben, dass es ok ist alle Exceptions abzufangen. Du hast nicht geschrieben, wann man das lassen sollte.
Das reicht eben nicht aus um den Sachverhalt voll zu beleuchten.

Original von herbivore
Ich denke du verwechselst oberste und unterste Ebene. Aber bis zur obersten Ebene (= Main) zu warten, wäre falsch. Normalerweise sind die EventHandler für Benutzeraktionen die Ebene der Wahl, um alles wegzufangen (und anzuzeigen).

Auch auf drunter liegenden Ebenen fange ich alle Exceptions, um aufräumen, aber dann gibt es natürlich ein rethrow.

Hier wieder ein schönes Beispiel dafür, wie weglassen von Informationen zu nem völlig falschen Bild führt. Es reicht eben nicht zu sagen man fängt alles. Die Einschränkungen unter denen man es tut sind enorm wichtig.
Bei EventHandlern für Benutzeraktionen. Vollkommen in Ordnung. Was nun oben oder unten ist, lass ich mal dahingestellt. Ich hab ja erklärt was ich damit meine. In der Informatik hat der Baum seine Wurzel oben und seine Blätter unten, und ein Stack wächst von unten nach oben.
Oder eben du wirfst die Exception weiter. Hast du auch nicht gesagt. Ist auch wichtig.

Diese Informationen kannst du nicht einfach weglassen. Das du das ordentlich machst glaub ich dir ja sogar, sonst wärst hier bestimmt nicht Moderator. Aber du sagst es eben nicht vollständig und das lässt ein falsches Bild entstehen. Man stellt ja solche Fragen nicht um zu überprüfen ob die anderen das auch wissen.

Ich meine der Unterschied zu den Einschränkungen und Bedingungen die du jetzt erst formulierst und dem hier muss doch auch dir deutlich sein

ich wollte damit auch nur sagen, dass ich eher alle Exceptions generisch abfange statt explizit auf bestimmte Exceptions zu warten. 🙂

Das ist genau das Problem was viele mit hinreichender und notwendiger Bedingung haben.
Das ist wie zu sagen "Ich fahre immer die maximale erlaubte Geschwindigkeit". Es ist also notwendig, dass die Geschwindigkeit erlaubt ist, damit ich die Geschwindigkeit Fahre. Gleichzeitig impliziere ich damit aber, dass wenn die Geschwindigkeit erlaub ist, fahre ich sie auch. Real siehen die hinreichenden Bedingungen aber anders aus. Wenn es Wetter, Straßenverhältnisse oder Leistung des Autos nicht zulassen, dann fahr ich eben nicht so schnell. Du hast quasi Letzteres einfach mal weggelassen und der Fahranfänger glaubt nun, er sollte immer das Maximum fahren.

27.04.2006 - 10:56 Uhr

Nun stell dir mal vor du verwendest die Funktion irgendwo wieder.
Woran merkst du, dass da was nicht geklappt hat? Garnicht. Oder willst du zurück ins Mittelalter zu Fehlercodes, die mühsam weiter nach unten gereicht werden können, oder einem statischen GetLastError()?

Wie gesagt auf unterster Ebene, wenn das Programm vorm Beenden steht, noch ne Fehlermeldung rauszuhauen und alle Exceptions zu fangen ist ok. Alles andere ist einfach unbrauchbar.

27.04.2006 - 10:24 Uhr

Das sollte man aber nur auf der untersten Ebene machen. Dann, wenn das Programm wirklich am abschmieren ist und die Exception nicht weiter nach unten gereicht werden kann. Alles andere ist very bad practice.

Dazu gibts ja sogar in der AppDomain noch das Event UnhandledException. Da gehört sowas eigentlich rein. Prinzipiell in Funktionen jede Exception abzufangen ist absolut nicht empfehlenswert. Klar soll das Programm gut aussehen. Aber das fällt einem mit Sicherheit auf die Füße, wenn man das Programm irgendwann mal wieder erweitern will. Man stelle sich mal vor beim Framework hätten die so gearbeitet. Dann würde da nichts mehr ne Exception werfen. Damit wär das ganze absolut unbrauchbar.

Von nem catch, log und rethrow halte ich genauso wenig. Exceptions führen selbstständig nen Stacktrace mit, also reichts wenn man sie einmal am Ende logt.

Es gibt 4 Gründe eine Exception abzufangen:

  1. man fängt eine bestimmte Exception ab, weil man damit rechnet
  2. man fängt eine bestimmte Exception ab, weil man sie behandeln kann
  3. man fängt alle Exceptions ab, weil man noch zusätzliche Informationen hinzugeben kann, und wirft dann eine neue Exception mit der Alten als InnerException
  4. man fängt alle Exceptions ab, weil es für das restliche Programm absolut ohne Auswirkungen ist
26.04.2006 - 18:12 Uhr

Wenn man nicht den Code hinter dem get ändern will, könnte man doch auch per new überschreiben. Wenn man das überschreiben will, lagert man den Code dafür in eine andere Funktion aus:


abstract class CSignal
{
	protected double m_value = 0.0;
	
	protected virtual double GetValue()
	{
		return m_value;
	}
	
	public double Value
	{
		get { return GetValue(); }
	}
}

class CSignalOut  : CSignal
{
	protected override double GetValue()
	{
		return base.GetValue();
	}
	
	public new double Value
	{
		get { return GetValue(); }
		set { m_value = value; }
	}
}

Ist aber auch nicht wirklich schön. Da diktiert die Ableitung quasi das Aussehen der Basisklasse.

Eine schönere Lösung könnte man machen, wenn CSignal nur ein Interface wäre:


interface CSignal
{
	double Value
	{
		get;
	}
}

class CSignalOut  : CSignal
{
	protected double m_value;
	
	double CSignal.Value
	{
		get { return Value; }
	}
	
	public double Value
	{
		get { return m_value; }
		set { m_value = value; }
	}
}

26.04.2006 - 00:31 Uhr

Ok, ich bin davon ausgegangen, du willst nur die Punkte irgendwie verbinden. Aber du willst ja eher eine Art Polygon draus machen, dass alle Punkte beinhaltet und möglichst wenig Volumen hat.

Blau wäre auf jeden Fall die konvexe Hülle. Dafür gibt es einige gute Algorithmen, wobei die meist auf 2-3 Dimensionen gelten. Aber ich glaub schon, dass du da einen findest der schneller ist. Googel sollte da eigentlich helfen.

Den anderen Fall, was du grün markiert hast, müsstest du mir noch etwas genauer erklären. Was für Bedingungen muss denn die Lösung erfüllen?

Ich meine man könnte da zum Beispiel einen Worst-Out-Greedy machen.
Das heißt du startest mit der konvexen Hülle. Jeder Punkt der da nicht drinen liegt, kann schonmal nicht Teil der Lösung sein. Und dann nimmst du solange Punkte raus, wie deine Lösung noch alle Bedingungen erfüllt. Dann hast du nicht unbedingt eine optimale Lösung, aber auf jeden Fall eine gute 😉
Nur stellt sich da eben die Frage: wann muss ein Punkt enthalten sein
Bzw. eher noch: wann muss ein Punkt nicht Teil der Lösung sein.

Andersherum könnte ein Best-In-Greedy auch zu einer guten Lösung führen.
Das würde ungefähr so aussehen:

  1. Initialisiere Lösungsmenge mit einem beliebigen roten Punkt
  2. Suche den roten Punkt, der der Lösungsmenge am nähsten ist
  3. Suche von diesem Punkt aus die 4 nächsten roten Punkte (wenn es schon so viele gibt), die Teil der Lösungsmenge sind, und möglichst einen 5 dimensionalen Körper bilden
  4. Füge alle Punkte die in diesem Körper enthalten sind zur Lösungsmenge hinzu
  5. Wenn noch nicht alle roten Punkte überdeckt sind gehe zu 2

Das beruht eben auf der Idee, dass ein Punkt der Nahe an der Lösungsmenge liegt, wenig neues Volumen hinzufügt. Was nicht ganz die Wahrheit ist, aber eben eine naive Approximation.

Vieleicht führt sogar eine Triangulation der gegebenen Punkte zu einer Lösung. Allerdings weiß ich nicht, wie eine Triangulation (z.B. Delaunay-Triangulation) in 5 Dimensionen aussieht, für dein 2D Beispiel ist es aber kein schlechter Lösungsansatz. Einfach noch wenn möglich die äußeren Kanten wegnehmen und den Rest ausmalen und fertig. (Beispiel siehe Anhang)

Ich hoffe man versteht mich 😜

Je nachdem, je besser du definierst was eine gültige Lösung ist, umso besser kann man Algorithmen dafür entwerfen 😉

25.04.2006 - 19:19 Uhr

Finde ich aber schon ne interessante Sache. Darüber hab ich mir noch keine Gedanken gemacht, ist mir auch noch nicht über den Weg gelaufen.

Also läuft es darauf hinaus, dass man im static-Konstruktor komplexere Sachen so gut es geht vermeiden sollte.

Da sollte man schon was tun. Ideal und intuitiv wäre ja, wenn der Konstruktor beim nächsten aufruf einfach nochmal ausgeführt wird.

25.04.2006 - 16:13 Uhr

Mich erinnert das ganze an das Steinerbaum Problem.
Du hast nen Graphen mit Knoten und ner Kostenfunktion (Knoten wären die Punkte, Kosten die Anzahl der Punkte die man durchläuft um von einem zum anderen zu kommen, Kanten kann man gerne den vollständigen Graphen wählen)
Du willst jetzt alle Knoten verbinden, das ganze soll minimal werden, und es können auch neue Knoten hinzugefügt werden. Die Kanten im resultierenden Steinerbaum müssten dann noch alle in Punkte übersetzt werden.

Das Steinerbaum Problem ist NP vollständig. Das heißt nen einfachen Algorithmus wirst du kaum finden. NP vollständige Algorithmen lassen sich nur durch cleveres Probieren aller Lösungen optimal bestimmen. Schnelle Algorithmen gibt es nur für Approximationen.
Du hast also 2 Möglichkeiten:

  1. Wenn dich wirklich NUR die kleinste Lösung interessiert, wirst du um Bruteforce oder Branch&Bound nicht drumrum kommen. Sprich du spielst alle Varianten durch und schaust was die Kleinste ist, und brichst an Stellen ab an denen man weiß, dass alle nachfolgenden Schritte keine bessere Lösung bringen.
    Man könnte z.B. als erstes mal die konvexe Hülle über die Punkte bestimmen, dann kann man schonmal ne ganze Menge Punkte die nur Umwege bedeuten würden wegschmeißen.

  2. Dir reicht eine Approximation, das heißt eine Lösung die nahe am Optimum liegt, aber eben nicht genau das Optimum ist. Dann würde ich empfehlen du schlägst Steinerbaum nach und überlegst, wie du dein Problem am besten auf einen der Algorithmen umbaust.

Es sei denn jemand hier hatte schonmal das gleiche Problem und sofort ne Lösung parat 😉

Für ne Hausaufgabe ist das ganze aber imo zu schwer 😉

25.04.2006 - 15:44 Uhr

Eigentlich blendet "new" nur die Warnung aus, die erscheint, wenn du es weglässt. Du sagst dem Compiler quasi, dass du weißt was du da tust 😉

25.04.2006 - 09:21 Uhr

Achso hab übersehen, dass er zwei unterschiedliche Namen verwendet.
Man muss schon die Funktion die aufgerufen werden soll übergeben.
Mich wundert dann nur, warum es kompiliert 😉

25.04.2006 - 09:16 Uhr

Das Problem mit dem FileSystemWatcher ist ganz einfach: er wurde nicht aktiviert.

SysWatcher.EnableRaisingEvents = true;

Mit dem Namen hat das nix zu tun.