2014-02-19 3 views
12

Die Struktur System.DateTime und ihre Cousine System.DateTimeOffset haben ihre Struktur Layout-Arten auf "Auto" festgelegt. Dies kann mit gesehen werden:Warum hat die System.DateTime-Struktur die Layout-Art Auto?

typeof(DateTime).IsAutoLayout /* true */ 

oder:

typeof(DateTime).StructLayoutAttribute.Value /* Auto */ 

oder es kann aus der IL gesehen werden, die erklärt:

.class public auto ansi serializable sealed beforefieldinit System.DateTime 
       ¯¯¯¯ 

Normalerweise wird ein struct (das ist ein Wert .NET Typ, der keine Enumeration ist), der mit C# geschrieben wurde, wird das Layout "Sequential" haben (es sei denn, ein StructLayoutAttribute wurde angewendet, um ein anderes Layout zu spezifizieren).

Ich suchte durch einige allgemeine BCL Assemblys, und DateTime und waren die einzigen öffentlich sichtbaren Strukturen, die ich mit diesem Layout gefunden habe.

Weiß jemand, warum DateTime dieses ungewöhnliche Struktur-Layout hat?

+1

Interessante Tatsache. Die Dokumentation zu 'Auto 'sagt * Die Laufzeitumgebung wählt automatisch ein geeignetes Layout für die Mitglieder eines Objekts im nicht verwalteten Speicher. Objekte, die mit diesem Enumerationselement definiert wurden, können nicht außerhalb von verwaltetem Code verfügbar gemacht werden. Der Versuch, dies zu tun, erzeugt eine Ausnahme. * Vielleicht wird dies verwendet, um die Verwendung nur in verwaltetem Code zu erzwingen. Grund dafür könnte sein, dass sich das Layout in der .NET-Historie mehrfach geändert hat (nur eine Annahme). Mehr: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx – ZoolWay

+0

'Auto' scheint in Ordnung, vielleicht sollte die Frage sein, warum so wenige andere Arten es verwenden. –

+0

@ZoolWay Ich dachte auch in diese Richtung. Beachten Sie, dass wir den Zeigertyp 'DateTime *' in C# immer noch verwenden können, mit 'unsicherem' Kontext, zum Beispiel funktioniert dieses Programm gut: 'unsafe { int [] memory = {123, 456, 789, 333, 666, 999,}; behoben (int * Zeiger = & Speicher [0]) { var pointer2 = (DateTime *) Zeiger; Console.WriteLine (Zeiger2-> DayOfWeek); Zeiger2 + = 2; Console.WriteLine (Zeiger2-> DayOfWeek); } } '. –

Antwort

10

Dies wird Spekulation erfordern, diese Entscheidung wurde eine lange Zeit gemacht, lange bevor .NET 1.0 ausgeliefert. Das Attribut auf System.DateTime ist bestenfalls eine Mikrooptimierung, die in .NET-Code nicht ungewöhnlich ist. Es ist etwas angemessen, die Struktur hat nur ein Feld, so dass es nie ein Problem mit dem Layout gibt. Die für die internen CustomAttribute-Strukturen wurden wahrscheinlich von demselben Programmierer ausgeführt. Das ist auch egal, nicht verwalteter Code sieht sie nie.

Die für System.DateTimeOffset wurde viel später und fast sicher ein Copy-Paste-Fehler gemacht.

Der Programmierer kam damit durch, kein Grund für die CLR, das Layout von der sequentiellen Version neu anzuordnen. Neuanordnung mit automatischem Layout tritt auf, wenn die Struktur Zwischenräume zwischen Feldern enthält, die groß genug sind, um in ein anderes kleines Feld zu passen. Nicht der Fall für DateTimeOffet.

Einige Chancen, dass Sie einen Microsoft-Guru darauf achten, wenn Sie einen Feedback-Bericht für DateTimeOffset einreichen. Es ist falsch afaik. Poste es zu connect.microsoft.com

+0

Ineteresting. Wird in Betracht ziehen, diesen Fehlerbericht zu archivieren.Aber die Struktur 'TimeSpan' ist so alt wie' DateTime', sie hat auch nur ein Instanzfeld, also warum wurde diese "Mikrooptimierung" nicht auf 'TimeSpan' angewendet? Hast du irgendeine Idee? –

+4

TimeSpan ist [ComVisible (true)], im Gegensatz zu DateTime. –

+0

[Zum Verbinden aufgefordert] (https://connect.microsoft.com/VisualStudio/feedback/details/820333/the-struct-type-system-datetimeoffset-has-layout-auto-even-if-it-has-two -instanz-Felder). –