Nullability of generic type arguments

150 views Asked by At

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 nullability
  • NullableAttribute contains information that I can't access from code - it won't help anything
  • Nullable.GetUnderlyingType doesn't always work as expected, seems useless in this context

and this leaves me with questions:

  1. Where would I need Nullable.GetUnderlyingType, where would it work as I expect, and where else is won't?
  2. How can I determine the nullability of a generic type argument?
  3. 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.

0

There are 0 answers