== oder String.Equals
-
Wenn du mal einen Blick auf den obigen Code wirfst, dann wirst du sehen, dass das eine ganz neue Klasse ist, die kein Bisschen des alten Codes enthält. Ich habe sehr wohl über den Algorithmus nachgedacht und einen völlig neuen gefunden: ich verwende jetzt einen Algorithmus der Marke "Knuth-Morris-Pratt". Irgendwie stimmt aber etwas noch nicht in dem Code. Ich kann meistens nicht den Endteil eines Knotens (</meinKnoten>) finden.
P.S.: Strings werden bei Methoden aber ohne das ref Keyword als Value-Types übergeben, obwohl sie eigentlich Reference-Types sind.
-
tommazzo schrieb:
P.S.: Strings werden bei Methoden aber ohne das ref Keyword als Value-Types übergeben, obwohl sie eigentlich Reference-Types sind.
Achja? Wo hast du denn das her? Würd mich ja mal interessieren.
Den String zu übergeben, heißt bereits, die Referenz zu übergeben. Du gewinnst nichts, wenn du eine Referenz auf die Referenz übergibst. Das ist völlig sinnlos.
-
Schreib dir mal ein kleines Testprogramm: in Main() deklarierst du einen String, den du mit irgendeinem Text initialisierst. Dann übergibst du den String an eine zweite Methode, die ihn modifiziert. Wenn du den String nachher in Main() nochmal am Bildschirm ausgibst, wirst du sehen, dass dieser String den selben Wert hat, mit dem du ihn initialisiert hast.
-
Bitte kauf Dir ein Buch oder lass die Hände vom Programmieren!
private void button_Click(object sender, System.EventArgs e) { string t = "Bar"; MessageBox.Show( t ); // Gibt Bar aus t = Foo( t ) ; MessageBox.Show( t ); // Gibt Foo aus } private string Foo( string s ) { return ( s = "Foo" ); }
-
Ich denk mal es ist eigentlich klar was er meint ..
using System; static class StringRefTest { public static void ChangeString(string s) { s = "muahahahahahhaha !!!!!"; } public static void Main() { string str = "original"; Console.WriteLine(str); // "original" ChangeString(str); Console.WriteLine(str); // "original" } }
Das liegt aber ganz bestimmt nicht daran, dass String als ValueType übergeben wird, denn das ist einfach nur an
der Versuch das Verhalten durch "Raten" zu erklären ..Das liegt halt einfach daran, dass wir einfach eine Referenz (s) auf ein anderes Objekt (mit dem Inhalt "muahahahahahhaha !!!!!")
zeigen lassen. Die "Original-Refernz" (str) ist dabei nicht beteiligt, da ihre Adresse kopiert wurde.tommazzo schrieb:
Strings werden bei Methoden aber ohne das ref Keyword als Value-Types übergeben, obwohl sie eigentlich Reference-Types sind.
Korrekter wäre es wohl zu sagen:
Strings imiteren das Verhalten von Value-Types, da sie immutable sind. Sie sind aber dennoch in jedem Fall Reference-Types.Wobei aber auch, so denke ich halt, klar ist was Optimizer meinte. Sieh dir zum Beispiel mal deine Methode GetKMP_Table() an.
Du übergibst hier den String vollkommen unnötigerweise per ref, denn du veränderst ihn nicht, wofür also das ref ?
Optimizer wird wohl gedacht haben, du versprichst dir Performance Steigerung in punkto CallByValue vs. CallByReference.
Würde zumindestens zu Antworten passen, wie etwa:Optimizer schrieb:
Den String zu übergeben, heißt bereits, die Referenz zu übergeben.
-
Uups, mit dem Beispiel war ich etwas voreilig, naja Morgenstund ...
-
OK, ich denke ich hab's jetzt begriffen
und werde die REFs entfernen.
Das hilft mir aber immer noch nicht bei meinem Problem. Nehmen wir mal an ich möchte diese XML Datei auslesen:<?xml version="1.0" encoding="utf-8"?> <myRootElement> <myStringNode>foo</myStringNode> <mastverNode> <myIntNode>2</myIntNode> </mastverNode> <myBoolNode>True</myBoolNode> </myRootElement>
Wenn ich nun "myStringNode" auslesen will bekomme ich "foo" als Rückgabestring.
Wenn ich allerdings "myBoolNode" auslesen will bekomme ich das zurück:True</myBoolNode> </myRootElement>
Aus irgendeinem Grund findet das Ding oft nicht das Ende des Knotens.
-
Hier ist noch einmal der Code zu meinem Problem (dieses Mal ohne REFs):
internal class NodeHandler { #region Knuth-Morris-Pratt algorithm /// <summary> /// generates a KMP search table for the specified search-string /// </summary> /// <param name="searchStr">the string for which the table should be generated</param> private static int[] GetKMP_Table(string searchStr) { int i, j; int[] next = new int[searchStr.Length + 1]; next[i = 0] = j = -1; do { if(j < 0 || searchStr[i] == searchStr[j]) next[++i] = ++j; else j = next[j]; } while(i < searchStr.Length - 1); return next; } /// <summary> /// uses the Knuth-Morris-Pratt algorithm to find the next occurance of the search string /// </summary> /// <param name="xmlText">our xml text</param> /// <param name="searchStr">the string we're looking for</param> /// <param name="next">the KMP jump table for the search string</param> /// <param name="startPos">the starting position</param> /// <param name="endPos">the max search position</param> /// <returns>the index of the first char of the found search string or -1 if the search string has not been found in xmlText</returns> private static int GetNextPos(string xmlText, string searchStr, int[] next, int startPos, int endPos) { int textLength = endPos - startPos + 1; int j = 0; // Knuth-Morris-Pratt algorithm for(int i = startPos; i < textLength; i++) { // endless loop executing as long as chars match for(;;) { if(xmlText[i] == searchStr[j]) { j++; if(j == searchStr.Length) return i - searchStr.Length + 1; break; } else { if(j == 0) break; else j = next[j]; } } } return -1; } #endregion #region FindNode /// <summary> /// finds the specified node in xmlText /// </summary> /// <param name="nBegin">out: the beginning of the found node (will be -1 if node was not found)</param> /// <param name="nEnd">out: the end of the found node (will be endPos if node was not found)</param> /// <param name="startPos">the starting position</param> /// <param name="endPos">the max search position</param> /// <param name="includeNodes">specified whether the nodes themselved will be included in nBeginning and nEnd</param> private static void FindNode(out int nBegin, out int nEnd, string xmlText, string node, int index, int startPos, int endPos, bool includeNodes) { string nodeBegin = '<' + node + '>'; int[] next; int foundCount = 0; nBegin = 0; nEnd = 0; // let's find nodeBegin next = GetKMP_Table(nodeBegin); while(foundCount < index) { nBegin = GetNextPos(xmlText, nodeBegin, next, nBegin, endPos); if(nBegin != -1) foundCount++; else { nEnd = endPos; return; } nBegin += nodeBegin.Length; } // let's find nodeEnd string nodeEnd = "</" + node + '>'; next = GetKMP_Table(nodeEnd); nEnd = GetNextPos(xmlText, nodeEnd, next, nBegin, endPos); if(nEnd == -1) { nEnd = endPos; return; } // check if the nodes themselves have to be included in the results and add them if necessarry if(includeNodes) { nBegin -= nodeBegin.Length; nEnd += nodeEnd.Length; } } #endregion internal static TXmlReader.ReaderReturnValue GetNodeContent(string xmlText, string masterNode, int mnIndex, string subNode, int snIndex) { int mnBegin, mnEnd, snBegin, snEnd; TXmlReader.ReaderReturnValue returnValue = new TXML.TXmlReader.ReaderReturnValue(); // let's find our masterNode if(masterNode.Length > 0) { FindNode(out mnBegin, out mnEnd, xmlText, masterNode, mnIndex, 0, xmlText.Length, false); if(mnBegin == -1) { returnValue.foundNode = false; return returnValue; } } else { mnBegin = 0; mnEnd = xmlText.Length; } // let's find our subNode FindNode(out snBegin, out snEnd, xmlText, subNode, snIndex, mnBegin, mnEnd, false); if(snBegin == -1) { returnValue.foundNode = false; return returnValue; } // get and return the substring returnValue.foundNode = true; returnValue.text = xmlText.Substring(snBegin, snEnd - snBegin); return returnValue; } }
Wer das Problem aus nächster Nähe sehen will kann sich hier ein Demo Programm herunterladen. Klickt einfach mal auf den Button "GetNodes" und wählt dann einen Knoten aus der Liste aus. Bei einigen wird der korrekte Wert angezeigt, bei anderen nicht. Wieso?
-
Hi,
internal static
schon mal was von oop gehört ?
warum baust du das Konzept nicht objektorientiert auf ?Du benutzt eine objektorientierte Sprache und versuchst auf Biegen und Brechen C zu programmieren.
*Kopfschüttel*
-
Könnten wir uns vielleicht mal auf das wirkliche Problem konzentrieren - wieso finde ich das Ende eines Knotens nicht?
Aber OK ich kann ja aus meinem NodeHandler eine Basisklasse machen, das löst mein kleines Problem aber trozdem nicht.