Ich verwende Reflection, um die Type
Eigenschaften von a zu durchlaufen und bestimmte Typen auf ihre Standardeinstellungen zu setzen. Jetzt könnte ich den Typ umschalten und default(Type)
explizit festlegen , aber ich würde es lieber in einer Zeile tun. Gibt es ein programmatisches Äquivalent zum Standard?
c#
reflection
default
tags2k
quelle
quelle
Antworten:
In der neueren Version von .net wie .net Standard
type.IsValueType
muss geschrieben werden alstype.GetTypeInfo().IsValueType
quelle
default(T) != (T)(object)default(T) && !(default(T) != default(T))
Sie dann ein Argument haben, spielt es keine Rolle, ob es eingerahmt ist oder nicht, da sie gleichwertig sind.default(T) != default(T)
Rückgabe falsch machen, und das ist Betrug! =)Array.CreateInstance(type, length)
.Warum nicht die Methode aufrufen, die Standard (T) mit Reflektion zurückgibt? Sie können GetDefault eines beliebigen Typs verwenden mit:
quelle
nameof(GetDefaultGeneric)
wenn Sie können, anstatt"GetDefaultGeneric"
Sie können verwenden
PropertyInfo.SetValue(obj, null)
. Wenn ein Werttyp aufgerufen wird, erhalten Sie die Standardeinstellung. Dieses Verhalten ist in .NET 4.0 und in .NET 4.5 dokumentiert .quelle
Wenn Sie .NET 4.0 oder höher verwenden und eine programmatische Version wünschen, bei der es sich nicht um eine Kodifizierung von Regeln handelt, die außerhalb des Codes definiert sind , können Sie eine erstellen
Expression
, kompilieren und im laufenden Betrieb ausführen.Die folgende Erweiterungsmethode verwendet a
Type
und ruft den Wert ab, derdefault(T)
über dieDefault
Methode für dieExpression
Klasse zurückgegeben wird:Sie sollten den oben genannten Wert auch basierend auf dem
Type
zwischenspeichern. Beachten Sie jedochType
, dass der vom Cache verbrauchte Speicher möglicherweise die Vorteile überwiegt, wenn Sie ihn für eine große Anzahl von Instanzen aufrufen und ihn nicht ständig verwenden.quelle
e.Compile()
. Das ist der springende Punkt bei Ausdrücken.e.Compile()
zwischengespeichert werden, aber unter der Annahme, dass diese Methode ungefähr 14x so schnell ist, zlong
. Benchmark und Ergebnisse finden Sie unter gist.github.com/pvginkel/fed5c8512b9dfefc2870c6853bbfbf8b .e.Compile()
eher zwischenspeichern alse.Compile()()
? dh Kann sich der Standardtyp eines Typs zur Laufzeit ändern? Wenn nicht (wie ich glaube), können Sie nur das Ergebnis und nicht den kompilierten Ausdruck im Cache speichern, was die Leistung weiter verbessern sollte.Warum sagen Sie, dass Generika nicht im Bilde sind?
quelle
Dies ist die optimierte Flem-Lösung:
quelle
return type.IsValueType ? typeDefaults.GetOrAdd(type, Activator.CreateInstance) : null;
Die gewählte Antwort ist eine gute Antwort, aber seien Sie vorsichtig mit dem zurückgegebenen Objekt.
Extrapolieren ...
quelle
Die Ausdrücke können hier helfen:
Ich habe dieses Snippet nicht getestet, aber ich denke, es sollte "typisierte" Nullen für Referenztypen erzeugen.
quelle
"typed" nulls
- erklären. Welches Objekt geben Sie zurück? Wenn Sie ein Objekt vom Typ zurückgebentype
, dessen Wert jedoch lautetnull
, kann es keine anderen Informationen als die vorhandenen enthaltennull
. Sie können einennull
Wert nicht abfragen und herausfinden, um welchen Typ es sich angeblich handelt. Wenn Sie NICHT null zurückgeben, sondern zurückkehren .. Ich weiß nicht was .., dann wird es nicht so handelnnull
.Ich kann noch nichts Einfaches und Elegantes finden, aber ich habe eine Idee: Wenn Sie den Typ der Immobilie kennen, die Sie festlegen möchten, können Sie Ihre eigene schreiben
default(T)
. Es gibt zwei Fälle -T
ist ein Werttyp undT
ein Referenztyp. Sie können dies sehen, indem Sie überprüfenT.IsValueType
. WennT
es sich um einen Referenztyp handelt, können Sie ihn einfach auf einstellennull
. WennT
es sich um einen Werttyp handelt, verfügt er über einen standardmäßigen parameterlosen Konstruktor, den Sie aufrufen können, um einen "leeren" Wert zu erhalten.quelle
Ich mache die gleiche Aufgabe wie diese.
quelle
Entspricht Drors Antwort, jedoch als Erweiterungsmethode:
quelle
Leichte Anpassungen an der Lösung von @Rob Fonseca-Ensor : Die folgende Erweiterungsmethode funktioniert auch mit .Net Standard, da ich GetRuntimeMethod anstelle von GetMethod verwende.
... und der entsprechende Unit-Test für diejenigen, denen Qualität am Herzen liegt:
quelle
quelle
Nullable<T>
Typen: Es wird nicht das Äquivalent zurückgegeben,default(Nullable<T>)
das sein solltenull
. Akzeptierte Antwort von Dror funktioniert besser.Das sollte funktionieren:
Nullable<T> a = new Nullable<T>().GetValueOrDefault();
quelle