Anscheinend Nullable<int>und int?sind im Wert gleichwertig. Gibt es Gründe, sich für einen anderen zu entscheiden?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Anscheinend Nullable<int>und int?sind im Wert gleichwertig. Gibt es Gründe, sich für einen anderen zu entscheiden?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Antworten:
Kein Unterschied.
int?ist nur eine Abkürzung für Nullable<int>, für die selbst eine Abkürzung ist Nullable<Int32>.
Der kompilierte Code ist genau derselbe, den Sie verwenden möchten.
Das ?Formular ist nur eine Abkürzung für den vollständigen Typ. Persönliche Vorlieben sind der einzige Grund, sich für eine andere zu entscheiden.
Alle Details hier .
Die Syntax
T?ist eine Abkürzung fürNullable<T>, wobeiTes sich um einen Werttyp handelt. Die beiden Formen sind austauschbar.
Während ich völlig einig , dass in den meisten Fällen die gleichen sind, ich kam vor kurzem in einer Situation, wenn es ist ein Unterschied zwischen diesen beiden. Für die blutigen Details siehe diese Frage , aber um Ihnen hier ein kurzes Beispiel zu geben:
void Test<T>(T a, bool b)
{
var test = a is int? & b; // does not compile
var test2 = a is Nullable<int> & b; // does compile
}
Die erste Zeile enthält die folgenden Fehlermeldungen:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
Wenn Sie neugierig auf den genauen Grund dafür sind, empfehle ich Ihnen wirklich, die bereits verknüpfte Frage zu überprüfen. Das Grundproblem besteht jedoch darin, dass wir in der Analysephase nach einem is(oder einem as) Operator, wenn wir einem ?Token gegenüberstehen, prüfen, ob die nächste Frage vorliegt Token kann als unärer Operator interpretiert werden ( &könnte einer sein) und wenn ja: Der Parser kümmert sich nicht um die Möglichkeit, dass das ?Token ein Typmodifikator ist, er verwendet einfach den Typ davor und analysiert den Rest so, als ob der ?Token waren ein ternärer Operator (daher schlägt die Analyse fehl).
Während also im allgemeinen int?und Nullable<int>untereinander austauschbar sind, gibt es einige Sonderfälle , wenn sie völlig unterschiedlichen Ergebnissen führen, weil, wie der Parser Code sieht.
testist also mit einer Klammer festgelegt var test = (a is int?) & b;. Kann auch mit fixiert werden var test = a is int? && b;, und da bein einfacher Wert Parameter (keine Nebenwirkungen auf Auswertung) scheint es seltsam zu bevorzugen &über &&.
?ist ein Schlüsselzeichen.
int?als ternäre Operation ( var test = a is int? <return if true> : <return if false>) interpretiert wird , nicht als nullable int.
boolÜberladungen finden Sie in der Dokumentation . Dies sind boolesche logische Operatoren (das &für bool) und boolesche bedingte logische Operatoren (das &&für bool). Beachten Sie, wie der erste dieser Unterabschnitte eindeutig als logisch bezeichnet wird . Denken Sie daran, dass es in C # keine Konvertierungen ("Casts") zwischen boolund numerischen Typen gibt!
Bei der Verwendung der Code-First-Entity-Framework-Generierung (EF) besteht anscheinend ein Unterschied zwischen beiden:
Wenn Ihre Entität eine Eigenschaft enthält, die wie folgt deklariert ist:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF generiert keine nullbare Eigenschaft und Sie müssen den Generator zwingen, sie wie folgt nullbar zu machen:
public class YourContext : DbContext
{
public DbSet<MyEntity> MyEntities{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional();
}
}
Auf der anderen Seite, wenn Sie Ihre Entität wie folgt deklarieren:
public class MyEntity
{
public int? MyNullableInt { get; set; }
}
Der EF-Generator generiert eine nullfähige Eigenschaft mit einem nullbaren Feld in der entsprechenden Datenbanktabelle.
Nullableirgendwo eine andere Definition haben, da Nullable<T>EF mit der integrierten Funktion den Unterschied zwischen beiden nicht erkennen kann. Selbst wenn die EF-Leute sie anders behandeln wollten, konnten sie es nicht.
Nullable ist ein generischer Typ, aber int? ist nicht.
Es gibt einige Szenarien, in denen Nullable über int verwendet werden sollte.
für zB: hier kann man nicht ersetzen Nullable mit int?
Wie können Sie den folgenden Code ändern, ohne Nullable zu verwenden ?
class LazyValue<T> where T : struct
{
private Nullable<T> val;
private Func<T> getValue;
// Constructor.
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
// Execute the delegate.
val = getValue();
return (T)val;
}
}
}
Nullable<T>es istNullable<int>