Ein bool ist ziemlich speziell, es geht zurück auf Dennis Ritchies Entscheidung, der C-Sprache keinen Bool-Typ zu geben. Das hat viele Chaos-, Sprach- und Betriebssystem-Designer verursacht, die es selbst hinzugefügt und inkompatible Entscheidungen getroffen haben.
Es wurde dem Winapi als BOOL Typedef hinzugefügt. Das ist das Standard-Marshalling, wenn Sie keinen anderen Typ erzwingen. Typedef-ed als int, um es kompatibel mit C zu halten, dauert 4 Bytes, wie Sie herausgefunden haben. Und richtet sich an 4, wie Sie herausgefunden haben, wie jeder Int tut.
Es wurde zu C++ hinzugefügt. Ohne eine Größenangabe wählen die meisten C++ - Compiler-Implementierungen ein einzelnes Byte für den Speicher aus. Vor allem der Microsoft C++ Compiler hat die wahrscheinlichste Implementierung durchgeführt, mit der Sie interagieren werden.
Es wurde als VARIANT_BOOL zu COM Automation hinzugefügt. Ursprünglich als das neue Erweiterungsmodell für Visual Basic gedacht, um die VBX-Einschränkungen loszuwerden, wurde es sehr populär und fast jede Sprachlaufzeit unter Windows unterstützt es jetzt. VB war damals stark von 16-Bit-Betriebssystem-Sensibilitäten betroffen, ein VARIANT_BOOL benötigt 2 Bytes.
Alle drei nativen Laufzeitumgebungen sind wahrscheinlich Ziele für Interop in einem C# -Programm. Klar, die CLR-Designer hatten eine sehr schwierige Wahl, da sie zwischen 1, 2 und 4 Bytes wählen mussten.Es gibt keine Möglichkeit zu gewinnen, während die CLR versucht, auf COM-Interop zu raten. Sie kann nicht wissen, ob Sie versuchen, mit einem C-basierten API- oder einem C++ - Programm zu interagieren. Also haben sie die einzig logische Wahl getroffen: keine von ihnen.
Eine Struktur oder Klassenart, die eine Bool enthält, ist nie blitable. Nicht einmal, wenn Sie [MarshalAs (UnmanagedType.U1)] anwenden, die es mit dem CLR-Typ kompatibel machen würde. Nicht so sicher, dass das eine gute Entscheidung war, aber es war die, die sie gemacht haben, damit wir uns damit befassen müssen.
Es ist sehr wünschenswert, eine blitable Struktur zu erhalten, die das Kopieren vermeidet. Dadurch kann systemeigener Code direkt auf den verwalteten Heap und Stack zugreifen. Ziemlich gefährlich und viele eine defekte Pinvoke-Deklaration hat den GC-Heap ohne den üblichen Vorteil der unsicheren Keyword-Warnung beschädigt. Aber unmöglich für Geschwindigkeit zu schlagen.
Sie erhalten eine blitable Struktur von nicht mit bool
. Verwenden Sie stattdessen byte
. Sie können das Bool immer noch zurückholen, indem Sie das Strukturelement mit einer Eigenschaft umhüllen. Verwenden Sie keine automatisch implementierte Eigenschaft, Sie müssen sich um die Position des Bytes kümmern. Also:
struct MyStruct
{
private byte _f;
public bool f {
get { return _f != 0; }
set { _f = value ? 1 : 0; }
}
}
Native Code ist unmerklich für die Eigenschaft. Machen Sie sich keine Gedanken über den Laufzeit-Overhead für den Getter und Setter, der Jitter-Optimierer macht sie unsichtbar und sie werden zu einer einzigen CPU-Anweisung.
'privaten Bool _f;' -> 'privaten _f Byte;'? – PetSerAl
Froh, dass ich es gut erklärt habe :) Danke. –
Danke, das war eine sehr detaillierte Erklärung. Obwohl ich verstehe, eine Eigenschaft in C++ könnte eine robuste Lösung sein, aber ich möchte immer noch wissen, warum in C# Bool Array fest, es Verhalten sehr seltsam, sieht aus wie seine Größe ist 1 Byte, aber seine Ausrichtung ist 4 Bytes. Wissen Sie, welche Magie hinter dem C# Marshalling auf dem in der Struktur eingebetteten Bool-Array steckt? –