Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem .NET ako pretypovať string na byte array?

Dajú sa v .NETe managed typy pretypovávať medzi sebou? Napr string na byte[]? Lebo zatiaľ som nenašiel spôsob ako sa na hodnotu nejakého managed typu pozeráť ako na hodnotu iného managed typu.

Viem si ukázať na string, vytvoriť byteArray a naň ukázať tiež a cez Span<T> ich skopčiť do byte array:

(
    let mojString = "Ľavá pŕhľava onakvejšô žriebä"
    use strPtr = fixed mojString
    let stringSpan = new Span<char>(strPtr |> NativePtr.toVoidPtr, mojString.Length)
    let bytes = Array.zeroCreate<byte>(mojString.Length * 2) // UTF16 - 1 char su 2 bytes
    use bytesPtr = fixed bytes
    let byteSpan = new Span<char>(bytesPtr |> NativePtr.toVoidPtr, mojString.Length)
    stringSpan.CopyTo(byteSpan)
    printfn "Bytes %A" bytes
)

leže práve to je ten problém že musím kopírovať. nedalo by sa to nejako obísť? aby som sa na jednu hodnotu dokázal pozerať cez 2 rôzne typy?

Předmět Autor Datum
U stringu se dá pomocí indexeru přistupovat k jednotlivým znakům, které odpovídají dvěma bytům.
Wikan 29.08.2019 08:14
Wikan
To nerieši moj problém. som v práci ale skúsim neskôr podrobnejšie rozpísať čo potrebujem
libertarian7 29.08.2019 17:59
libertarian7
zkus // pripadne ...ASCII.GetBytes(input); var result = System.Text.Encoding.Unicode.GetBytes(text…
MaSo 29.08.2019 13:08
MaSo
Ahoj 1. var result = System.Text.Encoding.Unicode.GetBytes(text) robí to isté čo môj príklad vytv…
libertarian7 29.08.2019 17:49
libertarian7
Ahoj, ja jsem Javista, ale predpokladam, ze string je v .NET immutable, takze to, co chces zrejme be…
MaSo 29.08.2019 19:12
MaSo
"String je v .NET immutable" To ze string je v .NET immutable je pravda len na urcitej urovni abstr…
libertarian7 30.08.2019 20:47
libertarian7
Tohle uz je na me moc .NETu...:-) Koukam, jake prasarny se s tim daji delat, kdyz muzes v podstate… poslední
MaSo 31.08.2019 09:21
MaSo

Ahoj

1.

var result = System.Text.Encoding.Unicode.GetBytes(text)

robí to isté čo môj príklad vytvorí byte array do ktorého SKOPÍRUJE znaky. Ja sa chcem vyhnúť práve tomu kopírovaniu. Vôbec to teda nerieši moju otázku

2. Ale keď ti môžem poradiť: používaniu ASCII kódovania sa radšej vyhni dnes je už dávno prekonané. A System.Text.Encoding.ASCII.GetBytes by ti sprznilo diakritiku. ASCII nepodporuje regionálne znakové sady a má zmysel len keď robíš anglickojazyčnú aplikáciu a šetríš každý byte. .NET interne ukladá všetky stringy ako UTF-16 na jeden znak je potrebné jedno 16 bit slovo (2 bajty / uint16 / word) lebo je to najrtýchlejšia varianta Unicode a ľahko sa s ňou pracuje na druhej strane je zas pamaťovo náročná a nehodí sa na nierktoré znakové sady . Ale ak chceš šetriť miestom tak použi UTF-8 to je kompromis medzi veľkosťou a šetrením miesta, ale omnoho tažšie sa s tým pracuje, už len také základné veci ako vypočítanie dĺžky reťazca sú pri UTF-8 náročnejšie lebo niektoré znaky zaberajú 8 bitov niektoré viac

Ahoj, ja jsem Javista, ale predpokladam, ze string je v .NET immutable, takze to, co chces zrejme bez kopirovani nepujde.

Pokud muj kod dela to same, co tvuj, tak je lepsi ten muj, pac je na jeden radek. :-)

To ASCII jsem tam dal proto, at si vyberes, pac nevim jak mas kodovane stringy ve svem programu...

"String je v .NET immutable"

To ze string je v .NET immutable je pravda len na urcitej urovni abstrakcie. behove prostredie ti bezne dostupnymi prostriedkami nedovoli menit hodnotu stringu a po kazdej operacii ti vracia novy string na novej adrese. Ak sa pozries pod "poklicku" zistit ze je to len mantra, ktoru opakuju programatori bez toho aby sa nad tym hlbsie zamysleli. Ved ako by sa tam tie znaky dostali, keby sa hodnota stringu nemohla menit? Ale podme na to poporiadku. Co sa deje pri vytvoreni stringu? Najprv sa alokuje pamat, dostanes pointer ukazujuci na miesto v pamati kde ten string je a potom na to miesto zapisujes znaky, teda nie ty ale konstruktor. A ked mas k dispozicii ten pointer tak na to miesto vies zapisovat kolko krat chces a prepisovat ho kolko len chces. Nikto ti v tom nezabrani. Teraz ti to dokazem:

using System;

class Program
{
    static unsafe void Main(string[] args)
    {
        var immutableString = "tak som immutable?";
        Console.WriteLine("Q: {0}", immutableString); //vypise "Q: tak som immutable?"
        fixed (char* ptrStr = immutableString)
        {
            var str2 = "ein";
            var chars = (char*)(long)ptrStr; //ochcali sme C# compiler
            for (var i = 2; i >= 0; i--)
            {
                *chars = str2[i]; chars++;
            }
            chars += (immutableString.Length - str2.Length - 1);
            *chars = '.';
            Console.WriteLine("A: {0}", immutableString); //vypise "A: nie som immutable."
            Console.ReadLine();
        }
    }
}

Ad GetBytes:

Na bezne ucely by som aj ja pouzil asi to built-in riesenie.

Ale pre moj ucel to budem potrebovat navrhnut tak aby som sa uplne vyhol kopirovaniu. To znamena ze nepouzijem managed typy. A namiesto stringu asi pouzijem stary dobry pointer na char.

Ale aj keby mi stacilo kopirovanie. Riesenie od MS je napisane prilis univerzalne s ohladom na bezpecnost tak aby bolo nepriestrelne a fungovalo za kazdych okolnosti co si ale vybera dan v podobe mensieho vykonu. Ja naopak potrebujem jednoucelove, ale co najrychlejsie riesenie.

Ale ked si pozries to riesenie od MS tak neni az take kratke a je plne runtime checkov, ktore su sice uzitocne pre vyvojarov pri ladeni ale zbytocne to cele spomaluju:

tuna to zacina https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/text/encoder.cs#L189

a tuna to pokracuje https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/text/unicodeencoding.cs#L438

Zpět do poradny Odpovědět na původní otázku Nahoru