Zoeken…


Syntaxis

  • Nullable<int> i = 10;
  • int? j = 11;
  • int? k = nul;
  • Datum Tijd? DateOfBirth = DateTime.Now;
  • decimale? Hoeveelheid = 1,0 m;
  • bool? IsAvailable = true;
  • char? Letter = 'a';
  • (type)? variableName

Opmerkingen

Nullable-typen kunnen alle waarden van een onderliggend type en null .

De syntaxis T? is steno voor Nullable<T>

Nullable-waarden zijn eigenlijk System.ValueType objecten, dus ze kunnen in en uit de doos worden geplaatst. Ook is de null van een nullable object niet hetzelfde als de null van een referentieobject, het is gewoon een vlag.

Wanneer een nulpunt van een object boksen, wordt de nulwaarde geconverteerd naar null en wordt een niet-nulwaarde omgezet in een niet-nulbaar onderliggend type.

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

De tweede regel leidt tot correcte, maar paradoxale code:

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

In het kort:

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

Een nullabel initialiseren

Voor null :

Nullable<int> i = null;

Of:

int? i = null;

Of:

var i = (int?)null;

Voor niet-nulwaarden:

Nullable<int> i = 0;

Of:

int? i = 0;

Controleer of een Nullable een waarde heeft

int? i = null;

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

Wat hetzelfde is als:

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

Verkrijg de waarde van een nullable type

Gegeven volgende nullable int

int? i = 10;

Als de standaardwaarde nodig is, kunt u er een toewijzen met de operator null GetValueOrDefault , de GetValueOrDefault methode of controleren of de waarde HasValue int int voor HasValue .

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

Het volgende gebruik is altijd onveilig . Als i nul ben tijdens runtime, wordt een System.InvalidOperationException gegenereerd. Als tijdens het ontwerp geen waarde is ingesteld, krijgt u de fout Use of unassigned local variable 'i' .

int j = i.Value;

Een standaardwaarde krijgen van een nullable

De methode .GetValueOrDefault() retourneert een waarde, zelfs als de eigenschap .HasValue false is (in tegenstelling tot de eigenschap Value, die een uitzondering .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
    }
}

Output:

0
1

Controleer of een parameter van het generieke type een nullable type is

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

Standaardwaarde van nulbare typen is nul

public class NullableTypesExample
{
    static int? _testValue;

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

Output:

nul

Effectief gebruik van onderliggende Nullable argument

Elk nullable type is een generiek type. En elk nulbaar type is een waardetype .

Er zijn enkele trucs die het mogelijk maken om het resultaat van de Nullable.GetUnderlyingType- methode effectief te gebruiken bij het maken van code met betrekking tot reflectie / het genereren van code:

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

Het gebruik:

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

Output:

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. De NullableTypesCache is als volgt gedefinieerd:

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow