GetSerializableMembers (FormatterServices) gibt das gleiche Feld zweimal zurück! Warum?

8

FormatterServices.GetSerializableMembers gibt geschützte und interne Felder zweimal für abgeleitete Typen zurück. Einmal als eine Instanz von SerializationFieldInfo und einmal als RtFieldInfo .

Ich finde das sehr verwirrend! Kann mir jemand helfen zu verstehen, warum Microsoft beschlossen hat, es so zu implementieren?

Ich habe ein Beispielprogramm geschrieben, das mein Problem reproduziert:

%Vor%

Ich würde erwarten, dass privateField und protectedField jeweils einmal gemeldet werden. Dies ist jedoch die tatsächliche Ausgabe beim Ausführen des Programms:

%Vor%

Wie Sie sehen können, erscheint protectedField zweimal mit unterschiedlichen Namen, aber mit dem gleichen Metadaten-Token, also ist es tatsächlich das gleiche Feld.

Kann jemand erklären, warum?

    
Mårten Wikström 01.03.2013, 20:31
quelle

2 Antworten

1

Dies scheint nicht so sehr mit den FormatterServices zu tun zu haben, sondern damit, wie die Reflektion funktioniert und wie sie von FormatterServices verwendet wird. Für die Type.GetFields -Methode, wenn sie mit BindingFlags.NonPublic verwendet wird (siehe: Ссылка ): "Only geschützte und interne Felder für Basisklassen werden zurückgegeben, private Felder für Basisklassen werden nicht zurückgegeben. "

Vollständig von allen Prüfungen bereinigt und auf Ihr Beispiel zugeschnitten, was FormatterServices zum Abrufen der Felder tut, ist im Grunde Folgendes:

%Vor%

Dies erzeugt die folgende Ausgabe für Ihre Beispielklassen:

%Vor%

Und FormatterServices filtert seine Ergebnisse einfach nicht, indem überprüft wird, ob es dasselbe Feld mehrmals vom selben Deklarationstyp enthält. Angesichts der Art und Weise, wie FormatterServices implementiert wird (Überprüfung der serialisierbaren Basistypen eines Typs), sollten sie wahrscheinlich so etwas wie den Filter von ReflectedType == DeclaringType:

machen

Hoffe, das hilft.

    
Alex 14.07.2013, 00:20
quelle
0

Nachdem ich es aus verschiedenen Blickwinkeln getestet habe, habe ich beschlossen, meine Antwort zu ändern.

Die Methode GetSerializableMembers () ist defekt, Die Duplikate sind keine korrekte Projektion des zugrunde liegenden Speichers. (was wirklich überraschend ist ..)

Ich schlage vor: t.GetType (). GetMembers (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

Und überprüfen Sie das eingehende Ergebnis für die Liste der Mitglieder.

Viel Glück.

    
G.Y 04.04.2013 06:54
quelle

Tags und Links