Bei einem generischen Typ T
in C # frage ich mich, wie man den Typ Q
erhält, was gleichbedeutend ist mit T?
für nicht-nullbare T
und T
für bereits nullable T
.
Die Frage ergab sich aus echtem Code. Ich möchte den Zugriff auf Parameter vereinheitlichen, die über die Abfragezeichenfolge in meiner ASP.NET-Anwendung übergeben werden. Und ich möchte einen Standardwert des gleichen Typs angeben, aber stellen Sie sicher, dass null
als Standardwert übergeben werden kann.
Gegenwärtig bin ich gezwungen, zwei Überladungen von FetchValue
- eins ohne Standardwert und eins damit zu haben:
Es funktioniert gut, aber ich frage mich, ob es möglich ist, beide Funktionen so zusammenzuführen.
In C ++ würde ich Type-Traits wie PromoteNullable<T>::type
mit zwei Spezialisierungen von PromoteNullable
sowohl für nullbare als auch für nicht nullbare Typen verwenden. Aber was ist mit C #?
Beantwortet nicht direkt die gestellte Frage, aber ich schreibe dies:
%Vor% Der Hauptteil des Codes existiert also nur einmal - und Sie können sogar den Aufrufcode verwenden, um null
als Standardwert zu verwenden, wenn er dies wünscht.
Selbst wenn Sie die gewünschte Parameterdeklaration erstellen könnten, wäre diese Zeile immer noch ein Problem:
%Vor% Wenn sich herausstellte, dass default_value
ein T?
und nicht T
war, dann funktioniert der obige Code nicht. Selbst wenn Sie einen Cast machen:
Es gibt immer noch ein Problem: Um von T?
auf T
zu konvertieren, muss der Compiler tatsächlich einen Aufruf einfügen, um die Eigenschaft Value
der Nullable zu erhalten. Aber dieser Aufruf wäre nicht gültig, wenn der Typ von default_value
nur T
wäre.
In C # Generics muss der Compiler ein Stück IL für die Methode erstellen. Es gibt keine Möglichkeit, einen optionalen Code einzufügen, der auf
Da Ihr Rückgabetyp T
ist und T
ein Werttyp ist, kann er nicht null sein.
Sie müssen also immer einen NULL-fähigen Typ übergeben, da Sie eine Null zurück haben möchten, oder?
Probieren Sie dies aus. Sie können einen Nullwerttyp ( i
) und einen normalen Referenztyp ( o
) übergeben:
Denken Sie daran, das ist alles Syntax foo, da Sie am Ende einen object
Typ für T haben. Dies ist jedoch erforderlich, da nur object
Null sein können.
Sie können die Einschränkung class angeben, um sicherzustellen, dass Aufrufer einen Referenztyp übergeben (der keine Nullwerte zulässt):
%Vor%In diesem Fall delegierst du die Verantwortung, T auf T zu werfen? wenn es für den Anrufer notwendig ist, was sowieso nett ist: er weiß es vielleicht besser!
Versuchen Sie Folgendes:
%Vor% Nullwert-Typen müssen ein Werttyp sein. Daher müssen Sie die Einschränkung auf struct
festlegen. Sie deklarieren den Typ T
als Nullable
und konvertieren den Typ, wenn ein Wert vorhanden ist. Andernfalls geben Sie default
vom Typ T
zurück, was in diesem Fall null ist. Wenn Sie diese Methode aufrufen, müssen Sie den Typ explizit wie folgt festlegen:
Zurückgeben einer Zeichenfolge
Da string
ein Nullwert-Referenztyp ist, geben Sie korrekt an, dass er nicht mit dieser Funktion verwendet werden kann. In diesem Fall würde ich ein neues struct
erstellen und stattdessen für Strings.
Rufen Sie die Funktion wie folgt auf.
%Vor%Tags und Links c# generics nullable typetraits metaprogramming