Diskuze: Nefunguje int.TryParse
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 25 zpráv z 25.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
dej si breakpoint a zjistis, co je v tom stringu. nebo si to dej vypsat.. beztah to bude prazdny string,nebo neco podobneho.
Nene, nejsem úplně blbá, ladit umím.
Přijde tam stejná hodnota jako z Chrome. Například "0" nebo "1" a stejně to
spadne...
Právě proto mě to tak strašně udivilo, až jsem se musela někde
zeptat...
nevím sice jak ten problém řešit, ale zkusil bych si udělat pro zajímavost malý test (omlouvám se, jestli tě to už napadlo). Zajímalo by mě co jak dopadne vyhodnocení:
int i = 0;
if(0==s.CompareTo(i.ToString()) // jen musíš zajistit, aby to předávalo "0" jako v to náhledu
{
// pokud se to dostane sem, tak to asi kódováním nebude
}
if(!int.TryParse(s, out i))
{ // něco
}
lol.. to jsem jeste nevidel Koukni se do tech postbacku prosim na hlavicky..
Není v tom stringu nějaký netisknutelný znak, třeba konec řádku nebo tak něco, který se ti v debuggeru neukáže? Kolik je délka toho stringu, je to opravdu 1?
Případně ještě zkus před prasováním zavolat na tom stringu .Trim()
Zkoušela jsi něco na tento způsob?
s = "0";
int i;
if(!int.TryParse(s, out i))
{ // něco
}
Problém by taky mohl nastat, kdyby v tom řetězci byla hodnota, která spadá do rozsahu bezznaménkového integeru, ale ne do znaménkového (např. 0x80001000, popř. dekadický ekvivalent).
Tady to vypadá, že někde máš špatně nějakou drobnost (čím déle ji hledáš, tím je ta drobnost menší). Někdy pomůže to nechat pár dní být a nechat pracovat podvědomí.
Tak jsem na to přišla, ale pořád tomu nerozumím.
Je to něco podobného, co píšete.
Z toho stringu, co mi chodí z prohlížeče jsem si udělala charArray, a co
nevidím, toto pole je jiné pokud data posílá Chrome a pokud je posílá
IE/Edge.
IE/Edge do toho pole přidává znaky uvozovek, které se však při ladění
vůbec neukazují, takže při vyhodnocování nakonec string není číslo
(nebo v mém případě potřebuju ohodnotit na datetime).
Snad je to vidět na přiložených obrázcích.
Vstupní string byl: 0:00:10 pro IE a 0:00:12 pro Chrome.
Takže jsem to musela vyřešit takovým hackem:
public static string IEHackforTime(string time)
{
string newTime = "";
var arr = time.ToCharArray();
foreach( var c in arr)
{
if (Char.IsNumber(c) || c==':' )
{
newTime += c.ToString(); // Pole má 12 znaků, StringBuilder v tomto případě nemá smysl
}
}
return newTime;
}
Zrovna tady bych ten Stringbuilder použil, jinak tě GC nebude mít rád, protože mu při každém průchodu vytvoříš spoustu nových objektů navíc (string je immutable, takže každé připojení písmenka vytváří novou instanci stringu)
jj, já vím. Tady zrovna by mělo ve výsledku být jen 7 stringů, 6 z toho zbytečných, nezdálo se mi, že to GC mělo tak zatížit, no, ale app by se měly psát správně to jooo
To uz pak zalezi na tom, jestli to bude volany treba jednou za den nebo 100x za minutu
Jojo, string builder je hodně chytrý.. kromě toho že to drží vnitřně v poli, tak těch polí má několik rozděleneých po určité velikosti (tuším že aktuálně je ta mez 84kb) tak aby se to nepresunulo do huge object poolu, kde je to vše o řád pomalejší
no právě, že to bude volané tak 20x za den v období 2 týdnů a pak půl roku ne...
Ohledně StringBuilderu je to trochu mýtus a od .NET 2.0 to už
neplatí.
StringBuilder také vytváří spoustu nových objektů, rozdíl je v něčem
jiném.
Když používáš StringBuilder, občas se nový objekt nevytvoří,
protože máš pre-allocated pole.
To ovšem nemůžeš dělat moc často, jinak bys dospěl ke kvadratickému
poměru stejně jako String, vysvětlím.
Hlavní trik je v tom, že StringBuilder vytváří nové objekty v lineárním poměru vůči vstupu, to znamená, že 1000 volání Append() alokuje ~1000/K polí a dalších objektů o celkové velikosti ~1000*L, kde K a L jsou nějaké velice malé konstanty.
String při 1000 volání concat alokuje 1000 polí o celkové velikosti ~10002, což je kvadratický poměr a tady je zádrhel a důvod, proč je SB občas lepší.
Obecná rada je nechytit se do premature optimalizací, takže nepoužívat StringBuilder jen tak.
Rule of thumb:
V opačném případě si nekomplikuj život, hezčí kód vyhrává.
Měl jsem za to, že když vytvoříš instanci SB s parametrem třeba 1000, tak vytvoří buffer o velikosti 1000 znaků a rovnou to do něj všechny znaky zapisuje, takže se nevytváří žádné další instance stringů navíc, teď jsi mě trochu zmátl
EDIT: Beru zpět to zmatení, blbě jsem to pochopil napoprvé
Není problém ve znakové sadě? Když jsem se s něčím takovým setkal, předpokládal jsem utf-8, což nebyla pravda.
To máš pravdu, jedná se o tu konstantu K, kterou uvádím, a kterou je hrozně těžké specifikovat obecně, defaultně by měla být 16.
Pokud bys použil StringBuilder(1000) a dal tam 10 znaků, máš 990 znaků overhead (a drobné kvůli alignmentu v paměti), pokud bys tam dal 1010 znaků, máš 990 znaků overhead. Když takovou metodu budeš volat velice často, prakticky se nedá odhadnout, jestli je lepší StringBuilder(16) nebo StringBuilder(1024)?
Profiler většinou ukazuje na přesný opak toho, co bys jako programátor předpokládal, používal jsem ho, když jsem opravdu musel a do jednoho případu mě vždy vyvedl z omylu, proto je lepší napsat hezčí kód (ať už to znamená cokoliv) a neřešit rychlost nebo paměť.
Podle toho tvého obrázku to nejsou uvozovky, ale LRM znak https://en.wikipedia.org/…o-right_mark
Skoro to vypadá, jako na nějaký speciální control, který v IE
neodstraňuje formátování a pošle ti to na server celé.
Tak podle všeho IE/Edge v metodě Date.toLocaleString()
a jí
podobných vkládá tyhle kódy, aby při internacionalizaci (např. do
arabštiny) byl text flow korektní. Ať už ji voláš kdekoliv, počítej s
tím, že UI Locale by se na server nemělo dostávat.
To vypadá, že je to ono.
V javascriptu opravdu volám .toLocaleTimeString, protože hodnotu potřebuji
zároveň i zobrazit a pak teprve volám Ajaxem metodu controleru.
Ale moc nerozumím tvé poslední větě:
Ať už ji voláš kdekoliv, počítej s tím, že UI Locale by se na server nemělo dostávat.
Jako, že nemám v JS volat .toLocaleTimeString?
Volat toLocaleString
bys na klientovi určitě měla ale tuhle hodnotu jenom zobrazuj a
neposílej na server.
Některá prostředí ti dokonce ani nemusí vrátit arabské číslice, to
záleží jen na nastavení locale klienta.
Na server musíš posílat něco invariantního.
V naší aplikaci (nikoliv MVC) používáme ISO normu normalizovanou na UTC
(toISOString
) nebo POSIX normu (getTime
), ale
záleží na tom, jaké knihovny podporuješ a s čím se ti bude lépe
pracovat, ISO je jistota.
No, ona to je malinkatá aplikace o 3 stránkách a potřebuju tam měřit čas, jak něco dlouho trvalo a pak ukládat do db. Právě jedena komplikace je volání metody GET s parametrem času. Přišlo mi nejjednodušší vyrobit z času string, nahradit dvojtečky za podtržítka a na serveru parsovat zpět. UTC je (v letním čase) o 2 hodiny jinak, na to by se pak taky nesmělo zapomenout... a počítat počet milisekund od půlnoci 1970 se mi moc nechtělo (getTime)... I když je fakt, že počet milisekund by se v URL parametru posílal nejlépe a odpadlo by i složité ruční ohodnocování, zda posílaný parametr je opravdu číslo, zařídil by to Attribut routing, to je fakt...
Jestli měříš čas a milisekundy jsou dostačující, tak je integer dost dobrá volba.
Také měříme a ukládáme čas, ale držíme ho v sekundách jako float
kvůli kompatibilitě s POSIX normou, jediný JS má totiž milisekundy jako
časovou jednotku, všechny ostatní knihovny jedou na sekundy a všechny
knihovny epochy podporují.
V databázi se s tím pak snadno pracuje, ať už děláš agregovaný SQL dotaz
nebo map-reduce.
Ohledně UTC - datum je časový okamžik, který může mít různé reprezentace, UTC není o 2 hodiny zpět proti SEC, je to stejný časový okamžik v jiném formátu, podobně jako můžeš napsat 23 == 0x17, pořád máš stejnou hodnotu. Na server a do databáze je nejlepší normalizovat právě z toho důvodu, abys mohla ignorovat zónu a vždy pracovala se stejnou hodnotou. Když to nedodržíš, začnou se dít ošklivé věci, lidé mají datum narození o den zpět, události se dějí v budoucnosti, atd. Na klientovi naopak vždy víš, že čas je UTC a můžeš ho převádět do zóny uživatele, což u amerických zón dělá dost velký rozdíl.
Přesnost je pro mě bohatě dostačující na sekundy.
Měla to být jednoduchá app, napsaná za 1-2 odpoledne, běžící pouze na
intranetu, žádné databázové složitosti, prostý CRUD promocí EF. Na
klientu maximálně jQuery...
Ale budu vědět pro příště
Díky moc za pomoc.
Zobrazeno 25 zpráv z 25.