So far I've worked with Nullable.GetUnderlyingType
and even NullabilityInfo.WriteState
to determine the nullability of types. This worked well - sometimes.
I'd like to know the nullability of the Dictionary<string, string?>
generic type arguments:
Type baseType = typeof(Dictionary<string, string?>)!;
Type[] gp = baseType.GetGenericArguments();
Assert.IsNull(Nullable.GetUnderlyingType(gp[0]));// Ok
Assert.IsNotNull(Nullable.GetUnderlyingType(gp[1]));// Fail
I can't use a NullabilityInfoContext
here, because I do only have the type, but not a reflection info object available.
Now my idea was to look for the compiler attribute NullableAttribute
:
string nat = "System.Runtime.CompilerServices.NullableAttribute";
Assert.IsTrue(gp[1].GetCustomAttributes(inherit: false).Any(a => a.GetType().ToString() == nat));// Ok
This does not really work, because:
Assert.IsTrue(gp[0].GetCustomAttributes(inherit: false).Any(a => a.GetType().ToString() == nat));// Ok
I can't access any information of the NullableAttribute
, so it doesn't help here.
I wonder why Nullable.GetUnderlyingType
returns null
for the second generic argument string?
? I expected the method to return typeof(string)
instead.
Even when I do typeof(Dictionary<string, string?>).ToString()
or or gp[1].ToString()
, I don't get any nullability information in the output.
My understanding now is, that
NullabilityInfo
helps to determine a reflection info objects nullabilityNullableAttribute
contains information that I can't access from code - it won't help anythingNullable.GetUnderlyingType
doesn't always work as expected, seems useless in this context
and this leaves me with questions:
- Where would I need
Nullable.GetUnderlyingType
, where would it work as I expect, and where else is won't? - How can I determine the nullability of a generic type argument?
- Is nullability more an IDE feature than it does affect anything real in the CLR?
I'd really like to have a way to find out, if the author of the code that I'm inspecting with reflections did use string
or string?
as generic parameter, because I want to switch my own code on that condition.
Update: I tried the reflection code I found in https://stackoverflow.com/a/71585611/10797322 , too, but the NullableAttribute
flags are always 0
, and the NullableContextAttribute
constructor parameter is always 1
- for BOTH generic type arguments.