Sök…


Syntax

  • Nullable<int> i = 10;
  • int? j = 11;
  • int? k = noll;
  • Datum Tid? DateOfBirth = DateTime.Now;
  • decimal? Mängd = 1,0 m;
  • bool? IsAvailable = true;
  • röding? Bokstav = 'a';
  • (typ)? variabelnamn

Anmärkningar

Nullable typer kan representera alla värden för en underliggande typ såväl som null .

Syntaxen T? är kortfattad för Nullable<T>

Nullable värden är System.ValueType objekt, så att de kan boxas och unboxas. null för ett nollbart objekt är inte detsamma som ett null för ett referensobjekt, det är bara en flagga.

När en nullable objektboxning konverteras null till null , och icke-nollvärdet konverteras till icke-nollbara underliggande typ.

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

Den andra regeln leder till korrekt, men paradoxal kod:

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

I kort form:

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

Initierar en nullable

För null :

Nullable<int> i = null;

Eller:

int? i = null;

Eller:

var i = (int?)null;

För icke-nollvärden:

Nullable<int> i = 0;

Eller:

int? i = 0;

Kontrollera om en nullable har ett värde

int? i = null;

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

Vilket är samma som:

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

Få värdet på en nullable typ

Givet efter nullable int

int? i = 10;

Om standardvärde behövs, kan du tilldela en med hjälp av nollkoalesceringsoperatör , GetValueOrDefault metoden eller kontrollera om nullable int HasValue före tilldelning.

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

Följande användning är alltid osäker . Om i är noll vid körning System.InvalidOperationException ett System.InvalidOperationException . Vid designtid, om ett värde inte är inställt, får du ett Use of unassigned local variable 'i' -fel.

int j = i.Value;

Få ett standardvärde från en nollstång

.GetValueOrDefault() returnerar ett värde även om egenskapen .HasValue är falsk (till skillnad från egenskapen Value, som kastar ett undantag).

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
    }
}

Produktion:

0
1

Kontrollera om en generisk typparameter är en nullable typ

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

Standardvärdet för nollbara typer är noll

public class NullableTypesExample
{
    static int? _testValue;

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

Produktion:

null

Effektiv användning av underliggande nullable argument

Varje nullable typ är en generisk typ. Och alla nollbara typer är en värdetyp .

Det finns några trick som gör det möjligt att effektivt använda resultatet av metoden Nullable.GetUnderlyingType när du skapar koder relaterade till reflektions- / kodgenereringsändamål:

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)));
    }
}

Användningen:

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.");

Produktion:

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. NullableTypesCache definieras enligt följande:

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow