HDSoftware Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Heisan I Clarion kan jeg gjøre slik: MyString = 'Hello World' MyString[2] = 'a' Message(MyString) Resultatet vil gi "Hallo World" Prøvde dette i VB men får beskjed at "Property CHARS is ReadOnly" Vet jeg kan gjøre det slik: MyString = mid(MyString,1,1) & "a" & mid(MyString,3,len(MyString)-3) men hallo.... må da være en enklere måte å gjøre det på... eller... Ole Lenke til kommentar
aadnk Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) I .NET, i motsetning til VB6, er strenger immutable - dvs. uforanderlige, hovedsaklig for å øke ytelsen til programmet. Kompilatoren kan dermed la flere streng-variabler peke til samme område uten at det er fare for at det kan skape konflikt dersom noen av disse strengene blir forsøkt å bli endret. Det er derfor ikke mulig å endre en streng i .NET etter den har blitt skapt. Dersom du føler det er behov for å lage/endre en streng i flere omganger, vil jeg anbefale at du bruker System.Text.StringBuilder-klassen: Dim oText As New System.Text.StringBuilder("Dtartstreng. ") ' Legger til tekst i enden av strengen oText.Append("Hallo ") oText.Append("verdn. ") ' * Modifikasjoner * oText = oText.Replace("verdn", "verden") oText.Chars(0) = "S" oText.Insert(0, "TTEST: ") ' Legger til 42 kopier av 'a' oText.Append("a", 42) oText.Append(". ") ' Legger til en ny linje oText.AppendLine("Ny linje kommer!") oText.AppendFormat("Denne {0} gjør det {1} å sette inn verdier i en streng.", _ "metoden", "enkelt") ' Fjerner en karakter oText.Remove(0, 1) ' Viser resultatet MessageBox.Show(oText.ToString) Endret 12. mars 2007 av aadnk Lenke til kommentar
Emancipate Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 > men hallo.... må da være en enklere måte å gjøre det på... eller... VB må da ha Left() og Right()? Det er enklere enn Mid()... Lenke til kommentar
GeirGrusom Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Nei nei nei nei nei... .NET Folkens! Lenke til kommentar
aadnk Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) > men hallo.... må da være en enklere måte å gjøre det på... eller...VB må da ha Left() og Right()? Det er enklere enn Mid()... 8139087[/snapback] Ytelsen blir ikke forbedret av den grunn - å bygge opp en ny streng ved å dele den opp i to deler og sette den sammen er ikke akkurat en optimal operasjon. Dessuten, rent kodemessig sparer en med Left() og Right() kun et par tastetrykk - nei, StringBuilder er nok å foretrekke. For øvrig, dersom det er VB6 du tenker på, kan en faktisk gjøre dette direkte med MID()-nøkkelordet: Dim sTest As String sTest = "Hello world" Mid(sTest, 2, 1) = "a" MsgBox sTest Endret 12. mars 2007 av aadnk Lenke til kommentar
j000rn Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) Ytelsen blir ikke forbedret av den grunn - å bygge opp en ny streng ved å dele den opp i to deler og sette den sammen er ikke akkurat en optimal operasjon. Dessuten, rent kodemessig sparer en med Left() og Right() kun et par tastetrykk - nei, StringBuilder er nok å foretrekke. 8139405[/snapback] Feil. Det er overkill å bruke stringbuilder på så enkle ting. Det vil faktisk gå treigere siden det krever litt ressurser å initialisere stringbuilder objektet. Om man skal f.eks. slå sammen mange string'er så vil stringbuilder være å foretrekke. MinString = MinString.SubString(0,5) & 'A' & MinString.SubString(6) Er rette måten å gjøre dette på i VB.Net. En liten hemmelighet er at i .Net er ikke strings imutable egentlig "MinString[6] = 'A'"-type kode kan man enkelt gjøre med unsafe kode i C#, men ikke i VB.Net. Uansett så gidder man som regel ikke dette om man ikke har spesielle behov for ytelse. Endret 12. mars 2007 av jorn79 Lenke til kommentar
HDSoftware Skrevet 12. mars 2007 Forfatter Del Skrevet 12. mars 2007 > men hallo.... må da være en enklere måte å gjøre det på... eller...VB må da ha Left() og Right()? Det er enklere enn Mid()... 8139087[/snapback] Spiller ingen rolle om man bruker right, left elle rmid for mitt vedkommende. Jeg vil endre en karakter i en streng og thats it. Skal se på string builder klassen. Tror kansje den har det jeg trenger Når det gjelder ytelse så spiller det ingen rolle i dette tilfellet da denn ekoden kunn skal kjøres en gang ved oppstart. Greia er at jeg skal endre karakterer i en lang streng på bakgrunn av et binær mønster og da blir kode med left, right eller mid rimelig ulesbart. Derimot kjøper jeg glatt den mid(ThisString,5,1) = "A" hvis det fungerer i VB.NET2005 da. Det vil jo vise seg :-D Ole Lenke til kommentar
GeirGrusom Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Kanskje du kan bruke en char array? Lenke til kommentar
j000rn Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 Kanskje du kan bruke en char array? 8140802[/snapback] Da må du først kopiere string'en over i en char array. Endre på en av char'ene og så kopiere alt til en ny string. Tungvindt... Tror også det vil være treigere enn .SubString eksempelet over. .SubString bruker faktisk unsafe kode Dim s as String = "tester" Dim c() as Char = s.ToCharArray() c(2) = 'Z' s = new string(c) Ex. på unsafe C# kode for å endre på en bokstav: unsafe private void Test() { string s = "tester"; fixed (char* sptr = s) sptr[2] = 'Z'; } Lenke til kommentar
GeirGrusom Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 høh, det der ante jeg ikke at var mulig. Du er en luring. Lenke til kommentar
j000rn Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 høh, det der ante jeg ikke at var mulig.Du er en luring. 8140940[/snapback] Regnet ikke med at folk ville tro på at strings ikke er imutable, så jeg måtte jo ha et lite bevis Lenke til kommentar
HDSoftware Skrevet 12. mars 2007 Forfatter Del Skrevet 12. mars 2007 Kanskje du kan bruke en char array? 8140802[/snapback] Da må du først kopiere string'en over i en char array. Endre på en av char'ene og så kopiere alt til en ny string. Tungvindt... Tror også det vil være treigere enn .SubString eksempelet over. .SubString bruker faktisk unsafe kode Dim s as String = "tester" Dim c() as Char = s.ToCharArray() c(2) = 'Z' s = new string(c) Ex. på unsafe C# kode for å endre på en bokstav: unsafe private void Test() { string s = "tester"; fixed (char* sptr = s) sptr[2] = 'Z'; } 8140924[/snapback] Haha. Den var god. Ole Lenke til kommentar
aadnk Skrevet 13. mars 2007 Del Skrevet 13. mars 2007 Feil. Det er overkill å bruke stringbuilder på så enkle ting. Det vil faktisk gå treigere siden det krever litt ressurser å initialisere stringbuilder objektet. Om man skal f.eks. slå sammen mange string'er så vil stringbuilder være å foretrekke. 8140452[/snapback] Det trodde opprinnelig jeg også, men etter å ha undersøkt saken inngående gjennom testing og eksperimentering fant jeg ut at StringBuilder faktisk er mer effektiv enn Mid() og Substring() - og, overraskende nok, gjorde sistnevnte metode det verst i testen: * Starting string test. State the amount of desired reruns: 500000 StringBuilder: Total time: 205 ms (391407233 ticks) Average time: 0,00041 ms (782,814466 ticks) Substring: Total time: 242 ms (461467517 ticks) Average time: 0,000484 ms (922,935034 ticks) Mid: Total time: 228 ms (434866320 ticks) Average time: 0,000456 ms (869,73264 ticks) Kildekoden for testapplikasjonen (husk å kjøre den kompilerte applikasjonen om du ønsker å teste det), finner du her: Klikk for å se/fjerne innholdet nedenfor Imports System.Text Module modTest Sub Main() Dim Reruns As Integer ' Initiating the test Console.WriteLine("Starting string test.") ' Get the amount of times to run the test Integer.TryParse(Query("State the amount of desired reruns"), Reruns) Do ' Execute the test Console.WriteLine() ' New line StringTest(Reruns) ' Continue doing the test until the user refuse to restart Loop Until Query("Do you want to restart? (Y, N)").ToUpper <> "Y" End Sub Public Sub StringTest(ByVal Reruns As Integer) Dim oWatches() As Stopwatch = {New Stopwatch, New Stopwatch, New Stopwatch} Dim sText As String = "Hello world.", sOutput As String, oStringBuilder As StringBuilder For Tell = 0 To Reruns ' Test string builder oWatches(0).Start() oStringBuilder = New StringBuilder(sText, sText.Length) oStringBuilder.Chars(1) = "a" sOutput = oStringBuilder.ToString oWatches(0).Stop() ' Test conventional method oWatches(1).Start() sOutput = Mid(sText, 1, 1) & "a" & Mid(sText, 3) oWatches(1).Stop() ' Test .NET-method oWatches(2).Start() sOutput = sText.Substring(0, 1) & "a" & sText.Substring(2) oWatches(2).Stop() Next ' Write the results WriteStatistics(oWatches(0), Reruns, "StringBuilder") WriteStatistics(oWatches(1), Reruns, "Substring") WriteStatistics(oWatches(2), Reruns, "Mid") End Sub Public Sub WriteStatistics(ByVal Watch As Stopwatch, ByVal Reruns As Integer, ByVal Name As String) ' Write the results Console.WriteLine(Name & ":") Console.WriteLine(MaxLenght(" Total time:", 20) & Watch.ElapsedMilliseconds & _ " ms (" & Watch.ElapsedTicks & " ticks)") Console.WriteLine(MaxLenght(" Average time:", 20) & Watch.ElapsedMilliseconds / Reruns & _ " ms (" & Watch.ElapsedTicks / Reruns & " ticks)") Console.WriteLine() End Sub Public Function Query(ByVal Question As String) As String ' Ask the user Console.Write(Question & ": ") ' Return the given answer Return Console.ReadLine End Function Public Function MaxLenght(ByVal Text As String, ByVal TotalSize As Integer) As String ' See if we need to remove or append to the string If TotalSize < Text.Length Then ' Returns only a portion of the original string Return Text.Substring(0, TotalSize) Else ' Returns the string filled to its upper limit Return Text & New String(" ", TotalSize - Text.Length) End If End Function End Module Lenke til kommentar
aadnk Skrevet 13. mars 2007 Del Skrevet 13. mars 2007 (endret) Regnet ikke med at folk ville tro på at strings ikke er imutable, så jeg måtte jo ha et lite bevis 8140962[/snapback] I følge Wikipedia har ikke dette noe relevans for hvorvidt objektet er å regne for å være immutable eller ikke: Immutability does not imply that the object as stored in the computer's memory is unwriteable. Rather, immutability is a compile-time construct that indicates what a programmer should do, not necessarily what he can do (for instance, by circumventing the type system or violating const correctness in C or C++). Endret 13. mars 2007 av aadnk Lenke til kommentar
j000rn Skrevet 13. mars 2007 Del Skrevet 13. mars 2007 Det trodde opprinnelig jeg også, men etter å ha undersøkt saken inngående gjennom testing og eksperimentering fant jeg ut at StringBuilder faktisk er mer effektiv enn Mid() og Substring() - og, overraskende nok, gjorde sistnevnte metode det verst i testen 8142025[/snapback] Du hadde rett string klassen inneholder faktisk funksjonalitet for å gjøre dette. internal unsafe void SetChar(int index, char value) { if (index >= this.Length) { throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index")); } fixed (char* chRef = &this.m_firstChar) { chRef[index] = value; } } Lenke til kommentar
GeirGrusom Skrevet 13. mars 2007 Del Skrevet 13. mars 2007 Ikke krangle med aadnk om Visual Basic, du kan ikke vinne. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå