LateApexEarlySpeed.Nullability.Generic
1.0.3
dotnet add package LateApexEarlySpeed.Nullability.Generic --version 1.0.3
NuGet\Install-Package LateApexEarlySpeed.Nullability.Generic -Version 1.0.3
<PackageReference Include="LateApexEarlySpeed.Nullability.Generic" Version="1.0.3" />
paket add LateApexEarlySpeed.Nullability.Generic --version 1.0.3
#r "nuget: LateApexEarlySpeed.Nullability.Generic, 1.0.3"
// Install LateApexEarlySpeed.Nullability.Generic as a Cake Addin #addin nuget:?package=LateApexEarlySpeed.Nullability.Generic&version=1.0.3 // Install LateApexEarlySpeed.Nullability.Generic as a Cake Tool #tool nuget:?package=LateApexEarlySpeed.Nullability.Generic&version=1.0.3
LateApexEarlySpeed.Nullability.Generic
Nullability annotation info reader for .net types. Key improvement compared with standard NullabilityInfoContext is for more nullability info support of Generic type.
Starting from .net 6, there is built-in Nullability related classes to help read nullability annotation info on members of type (NullabilityInfoContext
and so on). However, it is not possible to get annotated nullability state of members and parameters if their types are from generic type arguments:
class Class1
{
public GenericClass<string> Property { get; }
}
class GenericClass<T>
{
public T Property { get; }
}
PropertyInfo property = typeof(Class1).GetProperty("Property")!.PropertyType.GetProperty("Property")!;
NullabilityInfo state = new NullabilityInfoContext().Create(property);
Assert.Equal(NullabilityState.Nullable, state.ReadState); // expected nullability state of ‘string’ property is NotNull
this library can get NotNull state for this 'string' property whose type is from generic type argument:
NullabilityPropertyInfo propertyInfo = NullabilityType.GetType(typeof(Class1)).GetProperty("Property")!.NullabilityPropertyType.GetProperty("Property")!;
Assert.Equal(NullabilityState.NotNull, propertyInfo.NullabilityReadState);
There is no information to help infer nullability info of generic type arguments of 'root' type, so if 'root' type is generic type, this library accepts explicit nullability info of generic type arguments for 'root' type and then process all properties, fields, parameters as normal:
NullabilityPropertyInfo propertyInfo = NullabilityType.GetType(typeof(GenericClass<string>), NullabilityState.NotNull).GetProperty("Property")!;
Assert.Equal(NullabilityState.NotNull, propertyInfo.NullabilityReadState);
even if with nested properties:
class GenericClass<T>
{
public GenericClass2<int?, T> Property { get; }
}
class GenericClass2<T1, T2>
{
public T1 Property1 { get; }
public T2 Property2 { get; }
public string? Property3 { get; }
}
NullabilityPropertyInfo property = NullabilityType.GetType(typeof(GenericClass<string>), NullabilityState.NotNull).GetProperty("Property")!;
Assert.Equal(NullabilityState.NotNull, property.NullabilityReadState); // GenericClass2<int?, T>
NullabilityType type = property.NullabilityPropertyType;
Assert.Equal(NullabilityState.Nullable, type.GetProperty("Property1")!.NullabilityReadState); // int?
Assert.Equal(NullabilityState.NotNull, type.GetProperty("Property2")!.NullabilityReadState); // string
Assert.Equal(NullabilityState.Nullable, type.GetProperty("Property3")!.NullabilityReadState); // string?
Library also supports info of fields and parameters, take parameter as example:
class Class1
{
public GenericClass<string, string?, int, int?> Property { get; }
}
class GenericClass<T1, T2, T3, T4>
{
public GenericClass2<T1, T2>? Function(T2 p0, T3 p1, T4 p2, string p3, string? p4)
{
throw new NotImplementedException();
}
}
class GenericClass2<T1, T2>
{
public T1 Property1 { get; }
public T2 Property2 { get; }
public string? Property3 { get; }
}
NullabilityMethodInfo method = NullabilityType.GetType(typeof(Class1)).GetProperty("Property")!.NullabilityPropertyType.GetMethod("Function")!;
// GenericClass2<T1, T2>?
NullabilityParameterInfo returnParameter = method.NullabilityReturnParameter;
Assert.Equal(NullabilityState.Nullable, returnParameter.NullabilityState);
NullabilityType returnType = returnParameter.NullabilityParameterType;
Assert.Equal(NullabilityState.NotNull, returnType.GenericTypeArguments[0].NullabilityState); // string
Assert.Equal(NullabilityState.Nullable, returnType.GenericTypeArguments[1].NullabilityState); // string?
Assert.Equal(NullabilityState.NotNull, returnType.GetProperty("Property1")!.NullabilityReadState); // string
Assert.Equal(NullabilityState.Nullable, returnType.GetProperty("Property2")!.NullabilityReadState); // string?
// string? p0, int p1, int? p2, string p3, string? p4
NullabilityParameterInfo[] parameters = method.GetNullabilityParameters();
Assert.Equal(NullabilityState.Nullable, parameters[0].NullabilityState);
Assert.Equal(NullabilityState.NotNull, parameters[1].NullabilityState);
Assert.Equal(NullabilityState.Nullable, parameters[2].NullabilityState);
Assert.Equal(NullabilityState.NotNull, parameters[3].NullabilityState);
Assert.Equal(NullabilityState.Nullable, parameters[4].NullabilityState);
Calling entrypoint is static method NullabilityType.GetType()
which has 3 overloads:
NullabilityType GetType(Type type) // when type itself is not generic type
NullabilityType GetType(Type type, params NullabilityState[] genericTypeArgumentsNullabilities) // when type is generic type is generic type and its generic type arguments are not generic types
NullabilityType GetType(Type type, params NullabilityElement[] genericTypeArgumentsNullabilities) // when type is generic type and its generic type arguments are also generic type
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.