C# Language
Nicht zulässige Typen
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));
}
}