Also habe ich diese Klasse:
public class Foo<T> where T : ???
{
private T item;
public bool IsNull()
{
return item == null;
}
}
Jetzt suche ich nach einer Typeinschränkung, mit der ich alles als Typparameter verwenden kann null
. Das bedeutet alle Referenztypen sowie alle Nullable
( T?
) Typen:
Foo<String> ... = ...
Foo<int?> ... = ...
sollte möglich sein.
Wenn class
ich als Typeinschränkung verwende, kann ich nur die Referenztypen verwenden.
Zusätzliche Informationen:
Ich schreibe eine Pipes and Filter-Anwendung und möchte eine null
Referenz als letztes Element verwenden, das in die Pipeline übergeht, damit jeder Filter ordnungsgemäß heruntergefahren, bereinigt usw. werden kann.
IFoo<T>
als Arbeitstyp verwenden und Instanzen über eine Factory-Methode erstellen? Das könnte funktionieren.Antworten:
Wenn Sie bereit sind, eine Laufzeitprüfung im Konstruktor von Foo durchzuführen, anstatt eine Prüfung zur Kompilierungszeit durchzuführen, können Sie prüfen, ob der Typ keine Referenz oder kein nullbarer Typ ist, und in diesem Fall eine Ausnahme auslösen.
Mir ist klar, dass nur eine Laufzeitprüfung inakzeptabel sein kann, aber nur für den Fall:
Dann wird der folgende Code kompiliert, aber der letzte (
foo3
) löst eine Ausnahme im Konstruktor aus:quelle
static bool isValidType
Feld bei, das Sie im statischen Konstruktor festgelegt haben, überprüfen Sie dann einfach dieses Flag im Instanzkonstruktor und werfen Sie, wenn es sich um einen ungültigen Typ handelt, damit Sie nicht jedes Mal die gesamte Überprüfungsarbeit ausführen eine Instanz. Ich benutze dieses Muster oft.Ich weiß nicht, wie man ein Äquivalent zu OR in Generika implementiert . Ich kann jedoch vorschlagen, ein Standardschlüsselwort zu verwenden , um null für nullfähige Typen und einen Wert von 0 für Strukturen zu erstellen:
Sie können auch Ihre Version von Nullable implementieren:
Beispiel:
quelle
Ich bin auf dieses Problem gestoßen, weil es einfacher war, eine generische statische Methode zu wollen, die alles "Nullable" (entweder Referenztypen oder Nullables) annehmen kann, was mich zu dieser Frage ohne zufriedenstellende Lösung brachte. Also habe ich meine eigene Lösung gefunden, die relativ einfacher zu lösen war als die vom OP angegebene Frage, indem ich einfach zwei überladene Methoden hatte, eine, die a
T
und die Einschränkung hat,where T : class
und eine, die aT?
und hatwhere T : struct
.Dann wurde mir klar, dass diese Lösung auch auf dieses Problem angewendet werden kann, um eine Lösung zu erstellen, die beim Kompilieren überprüft werden kann, indem der Konstruktor privat (oder geschützt) gemacht und eine statische Factory-Methode verwendet wird:
Jetzt können wir es so verwenden:
Wenn Sie einen parameterlosen Konstruktor wollen, werden Sie nicht die Überladung bekommen, aber Sie können trotzdem so etwas tun:
Und benutze es so:
Diese Lösung hat nur wenige Nachteile. Zum einen bevorzugen Sie möglicherweise die Verwendung von 'new' zum Erstellen von Objekten. Ein weiterer Grund ist, dass Sie nicht
Foo<T>
als generisches Typargument für eine Typeinschränkung verwenden können, die Folgendes umfasst :where TFoo: new()
. Schließlich ist hier der zusätzliche Code, den Sie benötigen, insbesondere wenn Sie mehrere überladene Konstruktoren benötigen.quelle
Wie bereits erwähnt, können Sie keine Überprüfung der Kompilierungszeit durchführen lassen. Allgemeine Einschränkungen in .NET fehlen stark und unterstützen die meisten Szenarien nicht.
Ich halte dies jedoch für eine bessere Lösung für die Laufzeitprüfung. Es kann zur JIT-Kompilierungszeit optimiert werden, da beide Konstanten sind.
quelle
Eine solche Typbeschränkung ist nicht möglich. Gemäß der Dokumentation der Typeinschränkungen gibt es keine Einschränkung, die sowohl den nullbaren als auch den Referenztyp erfasst. Da Einschränkungen nur in einer Konjunktion kombiniert werden können, gibt es keine Möglichkeit, eine solche Einschränkung durch Kombination zu erstellen.
Sie können jedoch für Ihre Anforderungen auf einen Parameter ohne Einschränkungstyp zurückgreifen, da Sie immer nach == null suchen können. Wenn der Typ ein Werttyp ist, wird die Prüfung immer als falsch ausgewertet. Dann erhalten Sie möglicherweise die R # -Warnung "Möglicher Vergleich des Werttyps mit null", die nicht kritisch ist, solange die Semantik für Sie richtig ist.
Eine Alternative könnte sein, zu verwenden
anstelle der Nullprüfung, da Standard (T) wobei die Klasse T: immer null ist. Dies bedeutet jedoch, dass Sie nicht unterscheiden können, ob ein nicht nullbarer Wert nie explizit oder nur auf seinen Standardwert festgelegt wurde.
quelle
ich benutze
quelle
quelle