Warum ist das Folgende verboten?
Nullable<Nullable<int>>
während
struct MyNullable <T>
{
}
MyNullable<Nullable<int>>
ist NICHT
Warum ist das Folgende verboten?
Nullable<Nullable<int>>
während
struct MyNullable <T>
{
}
MyNullable<Nullable<int>>
ist NICHT
Das liegt daran, dass die struct-Beschränkung eigentlich bedeutet nicht löschbar'. da Nullable, obwohl es eine Struktur ist, nullable ist (den Wert null annehmen kann), ist die Nullable<int>
kein gültiger Typparameter für das äußere Nullable ist.
Dies wird deutlich in die Dokumentation der Zwänge
wobei T: Struktur
Das Argument type muss ein Wertetyp sein. Jeder Werttyp außer Nullable kann angegeben werden.
Weitere Informationen finden Sie unter Verwenden von nullbaren Typen (C# Programmierhandbuch).
Wenn Sie die Gründe dafür wissen wollen, brauchen Sie die Kommentare des Sprachentwicklers dazu, die ich nicht finden kann. Ich würde das jedoch unterstellen:
Das Zulassen des Äquivalents von int?? würde nur Verwirrung stiften, da die Sprache keine Möglichkeit zur Unterscheidung von Nullable <Nullable<null>>
und Nullable <null>
noch eine offensichtliche Lösung für die folgenden Fragen.
Nullable<Nullable<int>> x = null;
Nullable<int> y = null;
Console.WriteLine(x == null); // true
Console.WriteLine(y == null); // true
Console.WriteLine(x == y); // false or a compile time error!
Die Rückgabe von true würde bedeuten sehr komplexer und erheblicher Overhead bei vielen Operationen mit dem Typ Nullable.
Einige Typen in der CLR sind "besonders", z. B. Strings und Primitive, da der Compiler und die Laufzeitumgebung viel über die jeweils andere Implementierung wissen. Nullable ist in dieser Hinsicht auch etwas Besonderes. Da es bereits in anderen Bereichen special cased ist, ist das where T : struct
Aspekt ist keine so große Sache. Der Vorteil liegt im Umgang mit Structs in generischen Klassen, da keine von ihnen, abgesehen von Nullable, mit Null verglichen werden kann. Das bedeutet, dass das Jit sicher betrachten kann t == null
immer falsch zu sein.
Wenn Sprachen so konzipiert sind, dass zwei sehr unterschiedliche Konzepte interagieren können, kommt es häufig zu seltsamen, verwirrenden oder sogar gefährlichen Randfällen. Betrachten wir als Beispiel Nullable und die Gleichheitsoperatoren
int? x = null;
int? y = null;
Console.WriteLine(x == y); // true
Console.WriteLine(x >= y); // false!
Durch die Vermeidung von Nullables bei der Verwendung von struct generic constraint können viele unangenehme (und unklare) Randfälle vermieden werden.
Was den genauen Teil der Spezifikation betrifft, der dies vorschreibt aus Abschnitt 25.7 (Hervorhebung von mir):
Die Werttyp-Beschränkung legt fest, dass ein Typ-Argument ein Werttyp sein muss (§25.7.1). Jede nicht-nullbare Parameter, der die Werttyp-Beschränkung hat, erfüllt diese Beschränkung. Ein Typ-Parameter der die Werttyp-Beschränkung hat, darf nicht auch die Konstruktor-Beschränkung haben. Der System.Nullable-Typ spezifiziert die nicht-nullbare Werttyp-Beschränkung So können rekursiv konstruierte Typen der Formen T?? und Nullable
<
Nullbar<
T>>
sind verboten.
Ich glaube, Sie können nur nicht-nullbare Werttypen in Nullable
s. Da Nullable
selbst löschbar ist, ist eine Verschachtelung auf diese Weise verboten.
De http://msdn.microsoft.com/en-us/library/kwxxazwb.aspx
public Nullable( T value )
Art: T Ein Werttyp.
Nullable ist besonders, weil es explizite Unterstützung für Boxing und Unboxing von Nullable-Typen in die CLR eingebaut ist:
Wenn Sie die MSIL box
Anweisung gegen eine Nullable<T>
erhalten Sie tatsächlich eine null
als das Ergebnis. Es gibt keinen anderen Wertetyp, der beim Einrahmen eine Null ergibt.
Es gibt eine ähnliche und symmetrische Unterstützung für das Unboxing.
Der generische Typ-Parameter für Nullable muss selbst ein nicht-nullbarer Typ sein (d.h. ein Werttyp). Dies ist die C#-Compiler-Warnung, die ich erhalte, und es scheint Sinn zu machen. Sagen Sie mir, warum würden Sie so etwas überhaupt tun wollen? Ich persönlich sehe keinen Nutzen und auch wenig Sinn in einer solchen Deklaration.
Nullable ermöglicht es, einen Werttyp wie einen Referenztyp zu behandeln, in dem Sinne, dass der Wert entweder existiert oder nicht (null ist). Da ein Referenztyp bereits nullable ist, ist dies nicht zulässig.
Zitiert von MSDN :
Die Struktur Nullable(T) unterstützt nur die Verwendung eines Werttyps als nullable Typ, weil Referenztypen vom Design her nullbar sind.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.