2017-03-26 2 views
1

Die where T : struct-Einschränkung ermöglicht es, die Domäne akzeptabler Typparameter auf die Menge von Werttypen zu beschränken (im Vergleich zu der Obermenge von Typen, die Wert- und Referenztypen einschließen), verbietet aber auch Nullwerttypen, obwohl Nullable dies nicht tut bedeutet in modernen Versionen von C# unbedingt einen Referenztyp.Wie beschränke ich einen generischen Typparameter, um nur Nullable-Werttypen in C# zu akzeptieren?

Was wäre, wenn ich Werttypen mit zusätzlicher NULL-Zulässigkeit wie int?, DateTime? usw. akzeptieren möchte, während native Nullable-Referenztypen wie String, IList usw. abgelehnt werden? Ist es möglich, die Einschränkungen auf diese Weise zu definieren? Wie wenn es ist?

Ich bin eigentlich neugierig zu lernen, beide Szenarien zu implementieren: Wenn der als Parameter verwendete Typ muss sowohl Wert und nullable sein und wenn ein Nullwert Typ akzeptiert werden soll, sowie eine nicht Nullable Werttyp und Ich denke, dass diese Aspekte eng genug sind, um beide zu entschuldigen, also würde ich einen bescheidenen Kommentar über den zweiten Fall schätzen und eine Antwort wählen, die sie als eine bessere enthält (vorausgesetzt, dass eine andere auf andere Weise nicht wirklich besser ist), wenn mehr als Eine Antwort wird gesendet und ich muss wählen, aber was ich jetzt wirklich brauche, ist der erste Fall (um immer einen Typ zu verlangen, der sowohl Nullwert als auch Werttyp gleichzeitig ist) und ich glaube auch an den zweiten Fall wird ziemlich einfach angesichts der Kenntnis der ersten sein, ganz zu schweigen davon, es ist keine gute Art, darauf zu bestehen, 2 Fragen in einen zu kleben, so werde ich abs schätze und akzeptiere eine Antwort nur im ersten Fall.

+0

Haben Sie versucht, System.Nullable als Einschränkung zu verwenden? https://msdn.microsoft.com/en-us/library/b3h38hb0.aspx – linuxuser27

+1

leider generische Einschränkungen auf C# sind begrenzt und niemand kann eine Antwort mit einer Funktion, die nicht existiert, nicht einmal Eric Lippert :) –

+0

@ SelmanGenç D'oh! Stimmt. Ich vergesse diese Einschränkung immer wieder.Ich hatte VS nicht vor mir, also konnte ich es testen :) – linuxuser27

Antwort

2

Sie können nicht. Nullable<T> sind keine gültige Einschränkung für Generics in C#.

Wenn Sie so etwas wie class X<T,U> where T : Nullable<U> versuchen Sie erhalten folgende Fehlermeldung:

'U?' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.

Wenn Sie sowohl T und Nullable<T> als Methodenparameter akzeptieren müssen, können Sie einfach überschreibt bieten:

class X<T> where T : struct 
{ 
    public void R(T arg){ Console.WriteLine("Non nullable: {0}", arg);} 
    public void R(Nullable<T> arg){Console.WriteLine("Nullable: {0}", arg);} 
} 

Und Sie dann kann jede Version aufrufen:

X<int> r = new X<int>(); 
r.R((int?)4); 
r.R(4); 

In Ihrem Typ behandelt nur Nullable Werte können Sie einfach Constraint zu T:struct aber überall in Ihrer Klasse verwenden Sie Nullable<T> für Parameter und Felder.

Weitere Diskussionen zu bestimmten Aspekten - C# generic type constraint for everything nullable und verwandte Fragen.

1

Es ist nicht genau was Sie wollen, aber vielleicht könnten Sie eine Art Einschränkung von IConvertible verwenden? Als Schnittstelle ist es nullable und wird von Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Dezimal, DateTime, Char und String implementiert.

class MyClass<T> where T : IConvertible 
{ 
    //Etc 
} 
+0

Obwohl ich nicht das Gefühl habe, dass ich es kann akzeptiere dies, da es sich nicht unbedingt um eine Antwort auf die gestellte Frage handelt, lasst mich meinen aufrichtigen Dank für einen interessanten Beitrag aussprechen und eine Aufzählung machen. – Ivan

Verwandte Themen