Programujeme ve Visual Basic .NET - 23. díl - textové řetězce

Diskuze čtenářů k článku

lemravec  |  27. 01. 2005 15:07

chcem vas iba upozornit na nevhodne pouzivanie tzv. hungarian notation.
pouzivanie je zastarale a je v rozpore z objektovo orientovanym pristupom.
ak budete mat objekt Customer nazvete ho custNew ? odporucam standardy navrhovane
samotnym microsoftom (napr. newCustomer).

je vsak chvalyhodne ze ste sa vobec podujali na tento projekt a drzim palce.
p.s. tabulka characterov urcite mnohym pomoze



odporucam nasledujucu stranku:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/vxconcodingtechniquesprogrammingpractices.asp

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  27. 01. 2005 18:19

Zdravím,
maďarskou notací mám ve zvyku označovat primitivní typy (kterých je omezený počet) a privátní členy rozhraní - zde pro změnu působí divně názvy ve stylu newInteger nebo custString. Privátní instanci objektu Customer bych pojmenoval clsCustomer nebo clsNewCustomer, pokud by byla součást rozhraní, pak NewCustomer.
 
Za odkaz děkuji, názvoslovným a code-design zásadám určitě časem vyhradím aspoň jeden samostatný díl seriálu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Hladik M.  |  26. 01. 2005 07:22

Jak je to ale s retezci s pevnou delkou ve strukturach?
Pokud totiz je treba predat API fci promennou obsahujici retezec s pevnou delkou (tedy souvislou oblast v pameti), dochazi u VB.NET k problemu. Napriklad fce FindFirstFile a FindNextFile. Zkousel jsem po deklaraci promenne s typem struktura patricne retezce nastavit fci Space(X) ale k nicemu to nevedlo. Stale to hlasi chybu typu: Neplatny odkaz na objekt.
Pokud jste se nekdo s timto popral, dejte prosim vedet.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  26. 01. 2005 12:42

Zdravím, zkuste si prostudovat pasáž "Default Marshaling for Strings" na MSDN:
http://msdn.microsoft.com/library/en-us/cpguide/html/cpcondefaultmarshalingforstrings.asp
 
Jelikož VB.NET již nepodporuje řetězce pevné dílky, texty ve strukturách se nejčastěji vyměňují jako binární řetězec pevné délky, což se v .NET specifikuje MarshalAs atributem. Jinak je postup stejný, jako v předchozích verzích VB:
 

Imports System.Runtime.InteropServices 
Module modMain
Declare Sub FindFirstFileA Lib "Kernel32.dll" (fileName$, ByRef WFD As WIN32_FIND_DATA)
Sub Main()
Dim WFD As New WIN32_FIND_DATA()
FindFirstFileA("C:\*", WFD)
System.Console.WriteLine(WFD.FileName)
End Sub
End Module
Structure WIN32_FIND_DATA
Public FileAttributes%
Public lCreated%
Public hCreated%
Public lAccessed%
Public hAccessed%
Public lWrited%
Public hWrited%
Public lFileSize%
Public hFileSize%
Public lReserved%
Public hReserved%
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> Public FileName$
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 14)> Public shortFileName$
End Structure

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  26. 01. 2005 13:09

Samozřejmě v případech, kdy prostředí .NET nabízí srovnatelné funkce doporučuji využívat nativní metody .NET.
Ukazuje se, že často není ani tak důležité učit detaily jazyka jako spíš strukturu a funkce knihoven .NET.
Většina v praxi nejčastěji používaných záležitostí je už totiž v .NET jak naprogramována, tak zdokumentována.
 

Imports System, System.IO
Module modMain
Sub Main
For Each FI As FileInfo In New DirectoryInfo("C:\").GetFiles("*")
Console.WriteLine(FI.Name)
Next
End Sub
End Module

Souhlasím  |  Nesouhlasím  |  Odpovědět
Hladik M.  |  26. 01. 2005 13:24

Diky za odpoved.
Vyzkouseno->slape to=> smekam klobouk a jeste jednou dekuji.

Co se vsak tyka vyuziti metod DirectoryInfo implementovane v System.IO tak bohuzel musim zklamene rici ne. Tyto metody jsou dobre pro prochazeni lokalnich disku a relativne malo polozek (max 100ky). Pokud je v adresari tisice a vice polozek a navic je to sitovy disk, jsou doby nacitani struktury neunosne dlouhe (radove 10ky sekund). Na zeleze P4/2.4 + ethernet 100Mb. Stejny adresar TotalCommander zvladne za 1-2 sekundy.

Kdyztak udelam srovnavaci testik obou dvou zpusobu a pokud by se to hodilo, nebo budete mit zajem, muzu to sem dat do placu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  26. 01. 2005 15:39

Ano, to by mě zajímalo - pokud budou k dispozici zdrojáky obou srovnávacích případů, vyzkouším si je.
Jen tak pro první nástřel jsem si zkusil vypsat pomocí druhé ukázky obsah instalačního adresáře WindowsXP na naší vnitrofiremní síti - kolekce DirInfo byla naplněna prakticky okamžite a výpis byl ve dvou vteřinách dokončen (5700 souborů na P III 1,2 GHz).
Nemyslím si tudíž, že by zde měl být nějaký závažný rozdíl ve výkonu, ani k tomu nevidím důvod. Je ale nutné rozlišit dobu, kterou vyžaduje ověření přístupu na síťový prostředek. Pokud otevřete WinCommanderem síťovou složku, tento čas se spotřebuje na první připojení, další procházení adresářů je rychlé, ale v mé ukázce je každá instance třídy DirInfo spojena s novou autentifikací, proto je nutné ji při rekurzívním procházení složek reusovat.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Hladik M.  |  27. 01. 2005 09:31

Na Vase e-mail na Atlasu jsem Vam zaslal zdrojaky testiku obou dvou moznosti (API vs .NET). Dalsim zajemcum je muzu na vyzadani poslat e-mailem take.
Jinak se omlouvam, ze jsem zavedl vlakno na jine tema nez je aktualni tema v serialu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  27. 01. 2005 11:56

Děkuji, na Vaši ukázku jsem se díval - a .NET verze je skutečně výrazně pomalejší (pro můj výše zmíněný příklad) jde o poměr 380 ms / 8500 ms ve prospěch API verze, ale současně IMO trpí tím, na co jsem upozorňoval - pro každý podadresář vytváří novou instanci třídy DirectoryInfo, jehož konstruktoru předává novou cestu - z hlediska .NETu to znamená, že se znovu autentifikuje pro přístup ke podadresářům.
Je to zbytečné, protože odkaz na kolekci podadresářů máte v okamžiku vytvoření třídy DirectoryInfo již k dispozici přes metodu GetDirectories(). Váš kód prochází adresáře jen do jedné úrovně, ale pokud by prováděl rekurzi, měla by si funkce ExploreFolder() navzájem předávat referenci objekt DirectoryInfo (), nikoliv cestu, ze které si tu referenci musí znovu vytvořit.
S tématem debaty není problém - je to mnohem méně OT, než diskuse o Pythonu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
mio  |  25. 01. 2005 17:34

Dobrý den p. Petříku,
v článku je dle mého názoru pár drobných chyb:
...Důvodem, proč jsou v tomto seriálu  řetězce probírány po výkladu polí je ten, že pole jsou vnitřně reprezentovány jednorozměrným polem znaků a lze je proto převést na pole znaků metodou ToCharArray(),
...Dim chA As Char = "A"c, chA as Char = System.Char.Parse("Abeceda")  ... tak toto asi moc fungovat nebude
Dim chA As Char = "A"c, ch1 As Char  = "1"c, ch_ = " "c
Console.WriteLine(Char.IsPunctuation(ch_))      ' výstup: "True",  znak " "c není znak interpunkce ...to je pravda, takže FALSE
Přeji hezký zbytek dne. Milan
 

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  26. 01. 2005 01:18

Ano - děkuji mockrát za upozornění... 
Je fajn vidět, že někdo přistupuje k seriálu aktivně a konstruktivně.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Zasílat názory e-mailem: Zasílat názory Můj názor