Angenommen, Sie haben eine Klassendeklaration, z. B .:
%Vor%Nun, gibt es einen Weg im generischen Code, der Reflektion (oder irgendein anderes Mittel dafür) verwendet, dass ich folgern kann, dass myInt einen Standardwert zugewiesen hat, während myOtherInt dies nicht tut? Beachten Sie den Unterschied zwischen der Initialisierung mit einem expliziten Standardwert und dem Verlassen des impliziten Standardwerts (myOtherInt wird standardmäßig auf 0 initialisiert).
Aus meiner eigenen Forschung sieht es so aus, als ob es keine Möglichkeit dafür gibt - aber ich dachte, ich würde hier fragen, bevor ich aufhöre.
[Bearbeiten]
Auch bei nullfähigen Typen und Referenztypen möchte ich zwischen denen, die als null belassen wurden, und denen, die explizit auf null initialisiert wurden, unterscheiden. Dies ist so, dass ich sagen kann, dass Felder mit einem Initialisierer "optional" sind und andere Felder "obligatorisch" sind. Im Moment muss ich das mit Attributen machen - was mich in diesem Fall mit ihrer Informationsredundanz kritisiert.
Ich habe Ihren Code kompiliert und in ILDASM geladen und habe diesen
bekommen %Vor% Beachten Sie, dass die ldc.i4.7
und stfld int32 dummyCSharp.MyClass::myInt
Anweisungen zum Festlegen der Standardwerte für das Feld myInt zu sein scheinen.
Eine solche Zuweisung wird also tatsächlich als zusätzliche Zuweisungsanweisung in einem Konstruktor kompiliert.
Um eine solche Zuweisung zu erkennen, benötigen Sie eine Reflexion, um die IL der MyClass-Konstruktormethode zu reflektieren und nach stfld
(set fields?) - Befehlen zu suchen.
EDIT: Wenn ich dem Konstruktor explizit eine Zuweisung hinzufüge:
%Vor%Wenn ich es in ILDASM lade, habe ich Folgendes:
%Vor%Beachten Sie, dass die zusätzliche Zuweisung für myOtherInt, die ich hinzugefügt habe, hinzugefügt wurde, nachdem der Konstruktor der Object-Klasse aufgerufen wurde.
%Vor%Also da hast du es,
Jede Zuweisung vor ist der Aufruf des Konstruktors der Object-Klasse in IL ist eine Standardwertzuweisung.
Alles, was darauf folgt, ist eine Anweisung innerhalb des tatsächlichen Konstruktorcodes der Klasse.
Es sollte jedoch ein umfangreicherer Test durchgeführt werden.
ps. das hat Spaß gemacht: -)
Ein Standardwert ist ein Wert wie jeder andere. Es gibt keine Möglichkeit, zwischen diesen beiden Fällen zu unterscheiden:
%Vor%In beiden Fällen geben Sie ihnen den Wert 0, eine Art rettet Sie nur beim Tippen. Es gibt keinen magischen "standardmäßigen nicht initialisierten Wert" - sie sind beide null. Sie funktionieren genau gleich. Aber die Tatsache, dass Sie darüber nachdenken, deutet darauf hin, dass Sie ernsthaft von guten Ideen abweichen. Was machst du? Was ist dein spezifisches Bedürfnis? Sie stellen die falsche Frage;)
Folgendes würde ich tun, wenn ich dies als allgemeine Laufzeitfunktion erstellen möchte. Für Skalartypen würde ich ein Standardwertattribut erstellen und das zur Bestimmung der Standardität verwenden.
Hier ist eine Teillösung für die Aufgabe - ich bin mir sicher, dass es besser sein könnte, aber ich habe es einfach ausgeschaltet:
%Vor%Für Werttypen, die einen nullfähigen Typ für optionale Parameter verwenden, sollte funktionieren. Zeichenfolgen können auch initialisiert werden, um sie zu leeren, wenn sie nicht optional sind.
%Vor%Wie auch immer, das erscheint mir ein bisschen dreckig, ich würde bei den Attributen bleiben, um dies klar zu machen.
Vielleicht ist das nicht die einfachste Lösung ...
Sie können das defaultValue-Attribut verwenden, um den Wert wie folgt zu setzen:
Importieren Sie System.ComponentModel und System.Reflection
%Vor%Und dann den Standardwert mit Reflektion wiederherstellen:
%Vor%Wie wäre es mit einer generischen Struktur, die einen Wert und ein initialisiertes Flag enthält?
%Vor%Dann verwenden Sie dies anstelle der Mitglieder, die Sie über die Initialisierung von kennen müssen. Es ist eine ziemlich grundlegende Variation über eine faule Zukunft oder Versprechen.
Wenn du das willst, dann schau dir den Code unten an.
Es steht geschrieben in Oxygene [1], hoffe das ist kein Problem.
[1] oder Delphi Prism, wie es jetzt heißt
%Vor%Ausgabe:
%Vor% %Vor%Huseyints Vorschlag funktioniert nicht, weil Sie die "Verwendung der nicht zugewiesenen lokalen Variablen 'sp_id'"
erhaltenTags und Links c# reflection default