How can we reflect over the nullability of props, params etc e.g. for string vs string? with the new C# 8 nullability output? Is there a new api for that?
See https://blog.rsuter.com/the-output-of-nullable-reference-types-and-how-to-reflect-it/
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
Thanks for bringing this to our attention @RSuter It's a very good point.
Preview 1 is a bit early for this content, as some details are still being discussed and subject to change. I've tagged it for the .NET Core 3 release, and added a milestone to make sure we cover this in one of the later previews.
Is there already some discussions, description, info about that? Can you provide some links e.g. to GitHub issues?
It should be possible to figure this out via reflection, but not trivial.
The Nullable attribute is generated so that it stores the relevant flags, so that the flags are accessible via reflection.
Once you have the flags, you’d need to decode them (which requires traversing the tree of nested types). The decoding is similar to that of dynamic.
Here’s our doc on encoding:
https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-reference-types.md#annotations
I can also dig up the section of our tests that cover this, if that helps.
I'm curious to understand the scenarios where this is useful to get this information at runtime via reflection. Can you share some more details?
@jcouv From the blog post @RSuter references above:
I’m writing libraries to generate JSON Schema (NJsonSchema) and OpenAPI/Swagger specs (NSwag). These libraries rely heavily on reflection. I looked into the Nullable Reference Types feature because I’d really like to use it in these generators…
Specifically it would be needed here:
https://github.com/RSuter/NJsonSchema/blob/master/src/NJsonSchema/Generation/DefaultReflectionService.cs#L165
(The type parameter is coming from a property or parameter info)
A simple way would be to add support for the NullableAttribute there and set DefaultReferenceTypeNullHandling to NotNull but then it would be global for all assemblies and not check your context-based feature opt-in attributes
I’m pretty sure there are other scenarios, e.g. assembly based documentation generators (docfx?), etc.
Ideally there would be a .net standard 1.0 package with MemberInfo extensions to get the nullability info (it’s a compiler feature which works in all .net frameworks, right?) - one can only hope 🙂
Tagging @terrajobst @danmosemsft @jaredpar.
Was there a discussion of extending the reflection APIs to expose information about nullability. As explained above, I think it should be feasible with existing APIs, but that could likely be simplified.
Was there a discussion of extending the reflection APIs to expose information about nullability.
No, but I recently had the same thought. Historically, reflection APIs haven't been updated to reflect "common" conventions, such as extension methods, or dynamic. It pretty much exposes more or less raw metadata. This is especially painful for things like nullable and tuple names where getting the correct information from metadata is rocket science.
However, we should do a diff how Roslyn symbol APIs exposes these concepts and come up with a proposal for reflection. /cc @steveharter.
where getting the correct information from metadata is rocket science
That's why it should not be implemented by external libraries - mainly to avoid implementing it multple times (once per lib), ensure it's behaving correctly and the stuff just works even if there are internal changes...
And please don't just add this to .net standard 2.1 as this would mean that the API is only available in the latest runtimes and users using C# 8 in older project are left out...
And yes, potentially the same applies for tuple names as this information might be useful to generate correct JSON Schemas (I don't have a request for supporting this [yet]).
@jcouv can you point me at the code where this is already implemented?
Ref: https://codeblog.jonskeet.uk/2019/02/10/nullableattribute-and-c-8/ and
https://github.com/nodatime/nodatime/blob/master/build/NullableApiReviewer/Program.cs#L105
(this really looks complicated)
I'm moving this milestone out a bit. We shouldn't write the docs until we have a clear recommendation.
@RSuter some of the complication is due to the compiler generated attribute not having a field / property where the flag is set. That forced the code to do constructor argument parsing which isn't pretty. As of dev16.u1p1 there is a field now that consumers can read. Simplifies that a bit.
Ref: This new reflection api might also be used by the EF Core project: https://github.com/aspnet/EntityFrameworkCore/issues/10347
Putting this in the backlog, because I don't think the story is set correctly yet.
I implemented my own lib for nullability reflection: https://github.com/RicoSuter/Namotion.Reflection/blob/master/README.md#nullability-reflection-c-8
Now used in NSwag and NJS