Suche…


Syntax

  • Nullable<int> i = 10;
  • int? j = 11;
  • int? k = null;
  • Terminzeit? DateOfBirth = DateTime.Now;
  • Dezimal? Betrag = 1,0 m;
  • bool IsAvailable = true;
  • verkohlen? Buchstabe = 'a';
  • (Art)? Variablennamen

Bemerkungen

Nullwerttypen können alle Werte eines zugrunde liegenden Typs sowie null .

Die Syntax T? ist eine Abkürzung für Nullable<T>

Nicht zulässige Werte sind eigentlich System.ValueType Objekte. Sie können daher in Box- oder Unbox-Formaten eingeschlossen werden. Außerdem ist der null eines nullfähigen Objekts nicht gleich dem null eines Referenzobjekts, sondern lediglich ein Flag.

Wenn ein Objekt auf NULL festlegbare boxing wird der Nullwert umgewandelt null Referenz und Nicht-Null - Wert wird auf NULL-zugrunde liegenden Typen umgewandelt.

DateTime? dt = null;
var o = (object)dt;
var result = (o == null); // is true

DateTime? dt = new DateTime(2015, 12, 11);
var o = (object)dt;
var dt2 = (DateTime)dt; // correct cause o contains DateTime value

Die zweite Regel führt zu korrektem, aber paradoxem Code:

DateTime? dt = new DateTime(2015, 12, 11);
var o = (object)dt;
var type = o.GetType(); // is DateTime, not Nullable<DateTime>

In Kurzform:

DateTime? dt = new DateTime(2015, 12, 11);
var type = dt.GetType(); // is DateTime, not Nullable<DateTime>

Initialisierung einer nullbaren

Für null :

Nullable<int> i = null;

Oder:

int? i = null;

Oder:

var i = (int?)null;

Für Nicht-Nullwerte:

Nullable<int> i = 0;

Oder:

int? i = 0;

Prüfen Sie, ob ein Nullwert einen Wert hat

int? i = null;

if (i != null)
{
    Console.WriteLine("i is not null");
}
else
{
    Console.WriteLine("i is null");
}

Welches ist das Gleiche wie:

if (i.HasValue)
{
    Console.WriteLine("i is not null");
}
else
{
    Console.WriteLine("i is null");
}

Rufen Sie den Wert eines nullfähigen Typs ab

Gegebene folgende nullable int

int? i = 10;

Falls ein Standardwert erforderlich ist, können Sie einen mit dem Koaleszenzoperator " GetValueOrDefault Methode " GetValueOrDefault oder vor der Zuweisung prüfen, ob "nullable" in HasValue .

int j = i ?? 0;
int j = i.GetValueOrDefault(0);
int j = i.HasValue ? i.Value : 0;

Die folgende Verwendung ist immer unsicher . Wenn i zur Laufzeit null ist, wird eine System.InvalidOperationException ausgelöst. Wenn zur Entwurfszeit kein Wert festgelegt ist Use of unassigned local variable 'i' Fehler " Use of unassigned local variable 'i' angezeigt.

int j = i.Value;

Abrufen eines Standardwerts aus einer NULL-Eigenschaft

Die .GetValueOrDefault() Methode gibt auch dann einen Wert zurück, wenn die .HasValue Eigenschaft false ist (im Gegensatz zur Value-Eigenschaft, die eine Ausnahme .HasValue ).

class Program
{
    static void Main()
    {
        int? nullableExample = null;
        int result = nullableExample.GetValueOrDefault();
        Console.WriteLine(result); // will output the default value for int - 0
        int secondResult = nullableExample.GetValueOrDefault(1);
        Console.WriteLine(secondResult) // will output our specified default - 1
        int thirdResult = nullableExample ?? 1;
        Console.WriteLine(secondResult) // same as the GetValueOrDefault but a bit shorter
    }
}

Ausgabe:

0
1

Prüfen Sie, ob es sich bei einem generischen Typparameter um einen nullfähigen Typ handelt

public bool IsTypeNullable<T>()
{
    return Nullable.GetUnderlyingType( typeof(T) )!=null;
}

Der Standardwert für nullfähige Typen ist null

public class NullableTypesExample
{
    static int? _testValue;

    public static void Main()
    {
        if(_testValue == null)
            Console.WriteLine("null");
        else
            Console.WriteLine(_testValue.ToString());
    }
}

Ausgabe:

Null

Effektive Nutzung des zugrunde liegenden Nullable Streit

Jeder nullfähige Typ ist ein generischer Typ. Und jede Nullable Type ist ein Werttyp.

Es gibt einige Tricks, die es ermöglichen, das Ergebnis der Nullable.GetUnderlyingType- Methode effektiv zu verwenden , wenn Sie Code erstellen, der mit Reflektions- / Codegenerierungszwecken zusammenhängt:

public static class TypesHelper {
    public static bool IsNullable(this Type type) {
        Type underlyingType;
        return IsNullable(type, out underlyingType);
    }
    public static bool IsNullable(this Type type, out Type underlyingType) {
        underlyingType = Nullable.GetUnderlyingType(type);
        return underlyingType != null;
    }
    public static Type GetNullable(Type type) {
        Type underlyingType;
        return IsNullable(type, out underlyingType) ? type : NullableTypesCache.Get(type);
    }
    public static bool IsExactOrNullable(this Type type, Func<Type, bool> predicate) {
        Type underlyingType;
        if(IsNullable(type, out underlyingType))
            return IsExactOrNullable(underlyingType, predicate);
        return predicate(type);
    }
    public static bool IsExactOrNullable<T>(this Type type)
        where T : struct {
        return IsExactOrNullable(type, t => Equals(t, typeof(T)));
    }
}

Die Verwendung:

Type type = typeof(int).GetNullable();
Console.WriteLine(type.ToString());

if(type.IsNullable())
    Console.WriteLine("Type is nullable.");
Type underlyingType;
if(type.IsNullable(out underlyingType))
    Console.WriteLine("The underlying type is " + underlyingType.Name + ".");
if(type.IsExactOrNullable<int>())
    Console.WriteLine("Type is either exact or nullable Int32.");
if(!type.IsExactOrNullable(t => t.IsEnum))
    Console.WriteLine("Type is neither exact nor nullable enum.");

Ausgabe:

System.Nullable`1[System.Int32]
Type is nullable.
The underlying type is Int32.
Type is either exact or nullable Int32.
Type is neither exact nor nullable enum.

PS. Der NullableTypesCache ist wie folgt definiert:

static class NullableTypesCache {
    readonly static ConcurrentDictionary<Type, Type> cache = new ConcurrentDictionary<Type, Type>();
    static NullableTypesCache() {
        cache.TryAdd(typeof(byte), typeof(Nullable<byte>));
        cache.TryAdd(typeof(short), typeof(Nullable<short>));
        cache.TryAdd(typeof(int), typeof(Nullable<int>));
        cache.TryAdd(typeof(long), typeof(Nullable<long>));
        cache.TryAdd(typeof(float), typeof(Nullable<float>));
        cache.TryAdd(typeof(double), typeof(Nullable<double>));
        cache.TryAdd(typeof(decimal), typeof(Nullable<decimal>));
        cache.TryAdd(typeof(sbyte), typeof(Nullable<sbyte>));
        cache.TryAdd(typeof(ushort), typeof(Nullable<ushort>));
        cache.TryAdd(typeof(uint), typeof(Nullable<uint>));
        cache.TryAdd(typeof(ulong), typeof(Nullable<ulong>));
        //... 
    }
    readonly static Type NullableBase = typeof(Nullable<>);
    internal static Type Get(Type type) {
        // Try to avoid the expensive MakeGenericType method call
        return cache.GetOrAdd(type, t => NullableBase.MakeGenericType(t)); 
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow