Was sind die Anwendungsfälle für IsLittleEndian in der BitConverter-Klasse?

8

Ich war so glücklich, als ich IsLittleEndian field in BitConverter entdeckt habe. Ich dachte natürlich, dass es da sein sollte und ich sollte in der Lage sein, jeden Endian zu spezifizieren, den ich mag. Nun, mein Glück hielt nicht lange an. Habe einige Zeit gebraucht, bis ich herausgefunden habe, dass es keine Möglichkeit gibt, das Feld zu setzen. Das Feld ist readonly und im statischen Konstruktor nur true :

%Vor%

Es ist lustig, dass das Feld tatsächlich im Code verwendet wird. Zum Beispiel sieht die ToInt32 Methodenimplementierung so aus:

%Vor%

So scheint die ToInt32 perfekt in der Lage zu sein, mit kleinen und großen Endianern umzugehen.

Meine Frage ist: Wie kommt es, dass es einen sehr nützlichen Code gibt, der bereits implementiert ist und dort in der FCL sitzt, aber es gibt keine Möglichkeit, ihn zu benutzen (es sei denn, Sie fangen an, sich mit der Reflexion zu befassen)? Ist es nur, weil einige Entwickler die Frist nicht eingehalten haben und den Job zur Hälfte geschafft haben? Auch wenn, warum ist der Code nicht verfügbar, aber das Feld ist? Ich hoffe, es gibt einen guten Grund dafür.

Ich möchte mich klar machen. Ich brauche keine Lösung, um mit Big-Endian-Werten umzugehen. Ich habe eine Lösung. Die Lösung wird tatsächlich in meiner Frage gezeigt.

    
Alex Aza 20.06.2011, 03:28
quelle

7 Antworten

2

Die Antwort liegt in der Referenzquelle für die BitConverter-Klasse.

Der relevante Auszug ist:

%Vor%

Das Flag ist durch die Präprozessor-Direktive fest verdrahtet, weil sich die Endian-Eigenschaft der Architektur, für die eine bestimmte Version des Frameworks kompiliert wird, nicht ändert.

    
gmoody1979 23.07.2014, 11:39
quelle
5

Leider ist das IsLittleEndian -Feld nur dazu da, Sie zu informieren. Aber Jon Skeets MiscUtil Bibliothek hat einen schönen EndianBitConverter, der Little und Big Endian unterstützt. Es gibt auch endian-bewusste BinaryWriter / -Reader-Klassen.

Hier ist der Link: Ссылка

Edit: Tut mir leid, aber ich habe keine bessere Erklärung. Ich denke, das sollte in das Framework aufgenommen worden sein und ich vermute, dass der Code momentan da ist, so dass es einfach ist, den Konverter in eine andere Architektur zu portieren.

Aber diese Funktionalität zu offenbaren, ist ein bisschen komplexer, als nur das Feld öffentlich zu machen. Da der Konverter statisch ist, ändert das Ändern des Flags effektiv den globalen Status und in einem Szenario mit mehreren Threads wäre dies katastrophal. Der Weg zu gehen ist wahrscheinlich zwei BitConverter-Objekte zur Verfügung zu stellen, die Sie instanziieren und lokal verwenden können (das ist was MiscUtil tut). Dies erfordert zusätzliche Klassen und / oder Schnittstellen, also war es vielleicht ein Terminproblem und wurde vorerst fallen gelassen. Hoffen wir, dass es später hinzugefügt wird.

    
ollb 20.06.2011 04:10
quelle
3

Zuerst stellen wir fest, dass die Klasse BitConverter speziell für die Bitkonvertierung nur für den lokalen Prozessor entwickelt wurde. Aus diesem Grund ist IsLittleEndian schreibgeschützt. Als Ergebnis unterstützt es nicht die Konvertierung zu oder von Big-Endian, wenn der lokale Prozessor Little-Endian ist und umgekehrt.

Obwohl ich die Gründe für das Weglassen der Unterstützung für allgemeine Endianz nicht kenne, ist der logischste Grund für mich Leistung . Eine Klasse, die im gesamten Framework für den beabsichtigten Zweck (Umwandlung in und von der Endlichkeit des nativen Prozessors) weit verbreitet ist, sollte so leistungsfähig wie möglich sein. Durch Einschränkung der Allgemeinheit der Klasse wird ihre Leistung verbessert, indem die Fälle begrenzt werden, die behandelt werden müssen. Da nur Little-Endian unterstützt wird, ist es wahrscheinlich messbar schneller .

Okay, jetzt kommen wir zum Kernpunkt der Frage. Warum sollten die Autoren Code enthalten, um sowohl Little-Endian als auch Big-Endian zu behandeln, wenn das Gesamtdesign der Klasse nur einen davon unterstützen soll?

Auch hier können wir nur spekulieren. Aber die Antwort liegt wahrscheinlich in zwei Beobachtungen:

  • Der disassemblierte Code, der sich auf IsLittleEndian bezieht, ist leistungsmäßig ein unwichtiger Fall
  • tragbaren Code zu schreiben, wenn es die Leistung nicht beeinträchtigt, ist eine gute Softwareentwicklung

Der Grund dafür, dass der von der Methode ToInt32 kopierte Code unwichtig ist, liegt darin, dass er nur für nicht ausgerichteten Speicher verwendet wird. Der 99% -Code-Pfad ist ein direkt unsicheres "Memcpy" der Bits.

Sogar in dem Ausmaß, in dem die Konvertierung von nicht ausgerichteten Speicher auftritt, ist der Code, der sie verarbeitet, um eine Grßenordnung weniger effizient als die rohe Methode. Eine zusätzliche Bedingung beeinträchtigt die Leistung nicht wirklich.

Das Nettoergebnis ist:

  • Die Klasse BitConverter ist so effizient wie möglich für ihren begrenzten Zweck
  • Der Quellcode für BitConverter ist dennoch portabel für Big-Endian-Prozessorarchitekturen
Rick Sladkey 30.06.2011 04:28
quelle
1

Laut der MSDN-Dokumentation IsLittleEndian ist es sehr wichtig, Sie zu informieren (Ihre Programm oder die BitConverter-Klasse), ob die Architektur Little oder Big Endian ist. Ich weiß nicht, dass es einen beabsichtigten Gebrauch außerhalb davon gibt.

    
msarchet 20.06.2011 03:33
quelle
0

Siehe Ссылка , wenn Sie eine Implementierung wünschen, mit der Sie die endian-ness festlegen können.

    
logicnp 20.06.2011 04:02
quelle
0

Es wird intern basierend auf dem Architekturtyp festgelegt.

aus den Dokumenten :

"Verschiedene Computerarchitekturen speichern Daten unter Verwendung verschiedener Byte-Ordnungen." Big-Endian "bedeutet, dass das höchstwertige Byte am linken Ende eines Wortes steht." Little-Endian "bedeutet, dass das höchstwertige Byte am rechten Ende von a steht Wort. "

Bearbeiten:

Dies war eine Designentscheidung, die vom c # -Team getroffen wurde. Die Funktion kann beide Typen konvertieren, da sie für beide Arten von Systemen verwendet werden kann. Es liegt an Ihnen als Entwickler, es anders zu konvertieren.

"... Alle Methoden des BitConverters akzeptieren oder geben Byte-Arrays in der Endian-Reihenfolge des Systems zurück ..."

%Vor%

"In dem Fall, in dem die Daten niemals die Grenzen Ihrer Anwendung verlassen, funktioniert das tatsächlich gut."

Weitere Informationen finden Sie in diesem Artikel .

    
David Wick 20.06.2011 03:32
quelle
0

Ich bin mir ziemlich sicher, dass sie es auf true ohne Möglichkeit von false setzen, weil alle Versionen von Windows sind Little-Endian .

Nun ist das Problem, dass sie if (IsLittleEndian) in einer Klasse tun, die niemals IsLittleEndian auf etwas anderes als true setzt, höchstwahrscheinlich ein Fall-in-Fall-Szenario. Auf diese Weise wird, wenn es jemals eine Kompilierung der .NET BCL für big-endian geben muss, ein einfacher #if / #else um diese eine Zuweisung ausreichen, anstatt auch neuen Code schreiben zu müssen.

Ich wette Mono setzt false für einige Betriebssysteme und Architekturen.

Bearbeiten : Und ich hatte Recht. Mono macht folgendes . Technisch würde keiner der anderen Code Ergänzungen benötigen, außer dass sie aufgrund von Copyright-Problemen alles anders in Mono schreiben mussten.

%Vor%     
Joel B Fant 20.06.2011 04:37
quelle