C # generischer Typ-Constraint für alle NULL-Werte
So habe ich diese Klasse:
public class Foo<T> where T : ???
{
private T item;
public bool IsNull()
{
return item == null;
}
}
Nun bin ich auf der Suche für eine Art Einschränkung, die mir erlaubt, alles, was als Typ-parameter, werden können null
. Das bedeutet, dass alle Referenz-Typen sowie alle Nullable
(T?
) Typen:
Foo<String> ... = ...
Foo<int?> ... = ...
sollte möglich sein.
Mit class
als Typ-Einschränkung nur erlaubt mir den Verweis-Typen.
Zusätzliche Informationen:
Ich Schreibe eine pipes-und-Filter-Anwendung, und möchten einen null
Referenz als das Letzte Element, das geht in der pipeline, so dass jeder filter kann abgeschaltet schön, nicht Aufräumen, etc...
InformationsquelleAutor der Frage user2963836 | 2013-11-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie bereit sind, um einen Laufzeit-check-in Foo Konstruktor, anstatt einen compile-time check können Sie überprüfen, ob der Typ nicht einen Verweis oder nullable-Typ, und eine Ausnahme wird ausgelöst, wenn das der Fall ist.
Mir ist klar, dass nur mit einer Laufzeit überprüfen kann inakzeptabel sein, aber nur für den Fall:
Dann der folgende code kompiliert werden, aber die Letzte (
foo3
) wirft eine exception im Konstruktor:InformationsquelleAutor der Antwort Matthew Watson
Ich weiß nicht, wie das umzusetzen, entspricht ODER im Bereich der Generika. Allerdings kann ich vorschlagen, verwenden Sie Standard Schlüssel-Wort, um zu erstellen, null für nullable-Typen und der Wert 0 für Strukturen:
Könnte man auch implementieren Sie die version von Nullable:
Beispiel:
InformationsquelleAutor der Antwort Ryszard Dżegan
Ich lief in dieses Problem für einen einfacheren Fall zu wollen, eine statische generische Methode, die könnte etwas "nullable" (entweder Referenz-Typen oder Nullables), die brachte mich auf diese Frage keine zufriedenstellende Lösung. So kam ich mit meiner eigenen Lösung, die relativ leichter zu lösen als die OP genannte Frage, indem Sie einfach mit zwei überladenen Methoden, eine, die eine
T
und hat die Einschränkungwhere T : class
und einem anderen, das dauert einT?
und hatwhere T : struct
.Dann erkannte ich, dass die Lösung auch für dieses problem eine Lösung zu schaffen, ist überprüfbar ist zur compile-Zeit durch den Konstruktor private (oder protected) und die Verwendung einer statischen factory-Methode:
Nun können wir es wie folgt:
Möchten Sie einen parameterlosen Konstruktor, Sie wird nicht die Feinheit der überlastung, aber man kann immer noch etwas tun, wie dieses:
Und verwenden Sie es wie diese:
Gibt es einige Nachteile bei dieser Lösung ist, dass Sie vielleicht lieber mit 'new' zu konstruieren-Objekte. Ein weiterer ist, dass Sie nicht in der Lage sein zu verwenden
Foo<T>
als generic type Arguments für eine Art Einschränkung der so etwas wie:where TFoo: new()
. Schließlich ist das bisschen extra-code, den Sie brauchen, hier die erhöhen würde, vor allem, wenn Sie mehrere überladene Konstruktoren.InformationsquelleAutor der Antwort Dave M
So ein Typ-constraint nicht möglich. Nach der Dokumentation von Typ-Einschränkungen es gibt keine Einschränkung, die erfasst sowohl die null-Werte zulässt und die Referenz-Typen. Da Einschränkungen können nur kombiniert werden in einer Verbindung, es gibt keine Möglichkeit, diese Einschränkung durch Kombination.
Können Sie jedoch für Ihre Bedürfnisse zurückgreifen, um eine unconstraint type-parameter, da kann man immer überprüfen == null. Wenn der Typ ein Werttyp ist der Scheck wird einfach immer zu false ausgewertet. Dann wirst du vielleicht bekommen die R# warning "Möglich, Vergleiche von Wert-Typ mit null", die ist nicht kritisch, solange die Semantik ist die richtige für Sie.
Alternative sein könnte, zu verwenden
anstelle der null-check, da standardmäßig(T), wobei T : die Klasse ist immer null. Dies, jedoch, bedeutet, dass Sie nicht unterscheiden kann, ob ein null-Wert hat nie explizit gesetzt oder war einfach auf seinen Standardwert festgelegt.
InformationsquelleAutor der Antwort Sven Amann
Wie bereits erwähnt, können Sie nicht über eine compile-time check für Sie. Generische constraints in .NET sind äußerst mangelhaft, und nicht unterstützen, die meisten Szenarien.
Aber ich halte das für eine bessere Lösung für die run-time-Prüfung. Es können optimiert werden auf JIT-Kompilierung-Zeit, da sind Sie beide Konstanten.
InformationsquelleAutor der Antwort Aidiakapi
Benutze ich
InformationsquelleAutor der Antwort ela
InformationsquelleAutor der Antwort SeeSharp