Konwertuję coś z VB na C #. Masz problem ze składnią tej instrukcji:
if ((searchResult.Properties["user"].Count > 0))
{
profile.User = System.Text.Encoding.UTF8.GetString(searchResult.Properties["user"][0]);
}
Następnie widzę następujące błędy:
Argument 1: nie można przekonwertować z „obiektu” na „bajt []”
Najlepsze dopasowanie przeciążonej metody dla „System.Text.Encoding.GetString (byte [])” ma kilka niepoprawnych argumentów
Próbowałem naprawić kod oparty na tym poście, ale nadal nie udało mi się
string User = Encoding.UTF8.GetString("user", 0);
Jakieś sugestie?
searchResult.Properties["user"][0]
? Spróbuj rzucić go nabyte[]
pierwszym(byte[])
w wynikach wyszukiwania?Properties["user"][0]
jest typ . Jeśli jesteś pewien, że jest to tablica bajtów, możesz przesyłać w ten sposóbprofile.User = System.Text.Encoding.UTF8.GetString((byte[])searchResult.Properties["user"][0]);
Odpowiedzi:
Jeśli masz już tablicę bajtów, musisz wiedzieć, jakiego rodzaju kodowania użyto, aby dostać się do tej tablicy bajtów.
Na przykład, jeśli tablica bajtów została utworzona w następujący sposób:
Będziesz musiał przekształcić go z powrotem w ciąg taki jak ten:
Jeśli w odziedziczonym kodzie można znaleźć kodowanie użyte do utworzenia tablicy bajtów, należy je ustawić.
źródło
Przede wszystkim dodaj
System.Text
przestrzeń nazwNastępnie użyj tego kodu
Mam nadzieję, że to naprawię!
źródło
Możesz także użyć metody rozszerzenia, aby dodać metodę do
string
typu, jak poniżej:I użyj go jak poniżej:
źródło
ToASCIIByteArray
. Nienawidzę, kiedy dowiaduję się, że biblioteka, z której korzystam, korzysta z ASCII i zakładam, że używa UTF-8 lub czegoś bardziej nowoczesnego.źródło
źródło
Dlaczego nie należy używać Encoding.Default ...
Odpowiedź @ Randall używa
Encoding.Default
, jednak Microsoft podnosi ostrzeżenie :Aby sprawdzić, jakie jest domyślne kodowanie, użyj
Encoding.Default.WindowsCodePage
(1250 w moim przypadku - i niestety nie ma predefiniowanej klasy kodowania CP1250, ale obiekt można pobrać jakoEncoding.GetEncoding(1250)
).Encoding.ASCII
jest 7-bitowy, więc też nie działa, w moim przypadku:... i dlaczego zamiast tego należy zastosować kodowanie UTF-8 ...
Domyślne kodowanie jest mylące: .NET używa UTF-8 wszędzie jako prawdziwego domyślnego (kodowania 8-bitowe stały się przestarzałe pod koniec XX wieku, sprawdź np.
Console.OutputEncoding.EncodingName
*), Więc każda stała zdefiniowana w kodzie jest domyślnie kodowana w UTF-8 - więc należy tego użyć, chyba że źródło danych jest w innym kodowaniu.* To jest UTF-8 w moim przypadku, które jest bezpośrednim kłamstwem:
chcp
z konsoli Windows (cmd) zwraca 852 - i nie należy tego zmieniać, ponieważ zlokalizowane polecenia systemowe (takie jak ping) mają tę stronę kodową na stałeZgodnie z zaleceniami Microsoft:
Encoding.UTF8
zalecany przez innych jest przykładem uf kodowania UTF-8 i może być również używany bezpośrednio lub jako... ale nie zawsze jest używane
Kodowanie tablic bajtowych powinno „po prostu działać” w Unicode w krajach zachodnich, ale jak tylko przeniesiesz swój program do niektórych mniej obsługiwanych regionów (jak tutaj w Europie Wschodniej), to jest prawdziwy bałagan: w Czechach domyślne ustawienia systemu Windows (w 2020 roku!) MS niestandardowe 852 (aka Latin-2) na konsolę, 1250 jako Windows OEM, UTF-8 (65001) jako .NET (i inne) nowe domyślne i powinniśmy pamiętać, że niektóre zachodnie 8-bitowe UE dane wciąż są w 1252, podczas gdy starym 8-bitowym zachodnim standardem dla Europy Wschodniej był ISO-8859-2 (aka Latin-2, ale NIE taki sam Latin-2 jak 852). Używanie ASCII oznacza tekst pełen tofu i „?” tutaj. Tak więc do połowy XXI wieku ustaw wyraźnie UTF-8 .
źródło
Opierając się na odpowiedzi Ali , poleciłbym metodę rozszerzenia, która pozwala opcjonalnie przekazać kodowanie, którego chcesz użyć:
I użyj go jak poniżej:
źródło
Encoding encoding = Encoding.Default
powoduje błąd czasu kompilacji:CS1736 Default parameter value for 'encoding' must be a compile-time constant
Poniższe podejście będzie działać tylko wtedy, gdy znaki mają 1 bajt. (Domyślny Unicode nie będzie działał, ponieważ ma 2 bajty)
Prostota
źródło
char
istring
są z definicji UTF-16.string
a zatem UTF-16. UTF-16 nie jest domyślny; nie ma wyboru. Następnie dzielisz się nachar[]
jednostki kodu UTF-16. Następnie wywołujesz Convert.ToByte (Char) , który akurat konwertuje U + 0000 na U + 00FF na ISO-8859-1 i zmienia wszystkie inne punkty kodowe.char
byciu 16 bitów iConvert.ToByte()
wyrzuceniu ich połowy.Użyj tego
źródło
Udoskonalenie edycji JustinStolle (użycie BlockCopy przez Erana Yogeva).
Zaproponowane rozwiązanie jest rzeczywiście szybsze niż kodowanie. Problem polega na tym, że nie działa przy kodowaniu tablic bajtowych o nierównej długości. Jak podano, podnosi wyjątek poza granicami. Zwiększenie długości o 1 pozostawia końcowy bajt podczas dekodowania z ciągu.
Dla mnie potrzeba pojawiła się, gdy chciałem kodować od
DataTable
doJSON
. Szukałem sposobu kodowania pól binarnych na ciągi i dekodowania z powrotem na ciągbyte[]
.Dlatego stworzyłem dwie klasy - jedną, która otacza powyższe rozwiązanie (podczas kodowania z ciągów jest w porządku, ponieważ długości są zawsze równe), a drugą, która obsługuje
byte[]
kodowanie.Rozwiązałem problem nierównomiernej długości, dodając pojedynczy znak, który mówi mi, czy pierwotna długość tablicy binarnej była nieparzysta („1”), a nawet („0”)
Następująco:
źródło
Odpowiedzi na to pytanie udzielono wystarczająco wiele razy, ale w języku C # 7.2 i wprowadzeniu typu Span istnieje szybszy sposób na zrobienie tego w niebezpiecznym kodzie:
Należy pamiętać, że bajty reprezentują ciąg zakodowany w UTF-16 (w języku C # nazywany „Unicode”).
Niektóre szybkie testy porównawcze pokazują, że powyższe metody są około 5 razy szybsze niż ich implementacje Encoding.Unicode.GetBytes (...) / GetString (...) dla średnich łańcuchów (30-50 znaków), a nawet szybsze dla większych łańcuchów. Te metody również wydają się być szybsze niż używanie wskaźników w Marshal.Copy (..) lub Buffer.MemoryCopy (...).
źródło
Jeżeli wynikiem parametru „searchResult.Properties [„ user ”] [0]” jest ciąg znaków:
Kluczową kwestią jest to, że konwersję ciągu na bajt [] można wykonać za pomocą LINQ:
I odwrotnie:
źródło
Czy ktoś widzi jakiś powód, aby tego nie robić?
źródło
Convert.ToByte(char)
nie działa tak, jak myślisz. Znak'2'
jest konwertowany na bajt2
, a nie bajt reprezentujący znak'2'
. Użyjmystring.Select(x => (byte)x).ToArray()
zamiast tego.To działało dla mnie
źródło
Możesz użyć MemoryMarshal API, aby wykonać bardzo szybką i wydajną konwersję.
String
będzie niejawnie oddanych doReadOnlySpan<byte>
, jakMemoryMarshal.Cast
akceptuje alboSpan<byte>
alboReadOnlySpan<byte>
jako parametr wejściowy.Poniższy test porównawczy pokazuje różnicę:
źródło
Ta praca dla mnie, po czym mogłem przekonwertować umieścić moje zdjęcie w polu bajtu w mojej bazie danych.
źródło