Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reflect nullability with new C# 8 feature #9662

Closed
RicoSuter opened this issue Dec 18, 2018 — with docs.microsoft.com · 18 comments
Closed

Reflect nullability with new C# 8 feature #9662

RicoSuter opened this issue Dec 18, 2018 — with docs.microsoft.com · 18 comments
Assignees
Labels
blocked Blocked for some reason doc-idea Indicates issues that are suggestions for new topics [org][type][category] dotnet-csharp/svc Pri2 won't fix Issues that were closed as part of automated backlog grooming
Milestone

Comments

Copy link

RicoSuter commented Dec 18, 2018

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/


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

@BillWagner BillWagner added this to the 2019 - Quarter 1 milestone Jan 14, 2019
@BillWagner
Copy link
Member

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.

@RicoSuter
Copy link
Author

Is there already some discussions, description, info about that? Can you provide some links e.g. to GitHub issues?

@BillWagner BillWagner added this to To do in March 2019 via automation Feb 25, 2019
@BillWagner BillWagner modified the milestones: 2019 - Quarter 1, March 2019 Feb 25, 2019
@BillWagner BillWagner self-assigned this Feb 25, 2019
@jcouv
Copy link
Member

jcouv commented Mar 14, 2019

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?

@BillWagner
Copy link
Member

@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…

@RicoSuter
Copy link
Author

RicoSuter commented Mar 14, 2019

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

@RicoSuter
Copy link
Author

RicoSuter commented Mar 14, 2019

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 🙂

@jcouv
Copy link
Member

jcouv commented Mar 14, 2019

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.

@terrajobst
Copy link
Member

terrajobst commented Mar 14, 2019

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.

@RicoSuter
Copy link
Author

RicoSuter commented Mar 14, 2019

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]).

@RicoSuter
Copy link
Author

RicoSuter commented Mar 14, 2019

@jcouv can you point me at the code where this is already implemented?

@RicoSuter
Copy link
Author

RicoSuter commented Mar 14, 2019

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)

@BillWagner BillWagner removed this from To do in March 2019 Mar 14, 2019
@BillWagner BillWagner modified the milestones: March 2019, 2019 - Quarter 2 Mar 14, 2019
@BillWagner
Copy link
Member

I'm moving this milestone out a bit. We shouldn't write the docs until we have a clear recommendation.

@jaredpar
Copy link
Member

@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.

@RicoSuter
Copy link
Author

Ref: This new reflection api might also be used by the EF Core project: dotnet/efcore#10347

@BillWagner BillWagner removed this from the 2019 - Quarter 2 milestone Jul 1, 2019
@BillWagner BillWagner added this to the September 2019 milestone Jul 1, 2019
@nmain
Copy link

nmain commented Aug 21, 2019

@BillWagner BillWagner added this to To do in September 2019 via automation Sep 3, 2019
@BillWagner
Copy link
Member

Putting this in the backlog, because I don't think the story is set correctly yet.

@BillWagner BillWagner added this to To do in Content for C# 8 / VB 16 via automation Sep 30, 2019
@BillWagner BillWagner removed this from To do in September 2019 Sep 30, 2019
@BillWagner BillWagner modified the milestones: September 2019, Backlog Sep 30, 2019
@RicoSuter
Copy link
Author

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

@BillWagner BillWagner removed this from To do in Content for C# 8 / VB 16 Oct 10, 2019
@BillWagner BillWagner added the blocked Blocked for some reason label Oct 10, 2019
@BillWagner BillWagner added this to To do in C# Guide reorganization via automation Oct 10, 2019
@BillWagner BillWagner added doc-idea Indicates issues that are suggestions for new topics [org][type][category] and removed Source - Docs.ms labels Oct 14, 2019
@PRMerger8 PRMerger8 added the Pri2 label Jan 16, 2021
@dotnet-bot dotnet-bot added the won't fix Issues that were closed as part of automated backlog grooming label Jan 25, 2021
@dotnet-bot dotnet-bot removed this from To do in C# Guide reorganization Jan 25, 2021
@dotnet-bot
Copy link
Contributor

This issue has been closed as part of the issue backlog grooming process outlined in #22351.

That automated process may have closed some issues that should be addressed. If you think this is one of them, reopen it with a comment explaining why. Tag the @dotnet/docs team for visibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked for some reason doc-idea Indicates issues that are suggestions for new topics [org][type][category] dotnet-csharp/svc Pri2 won't fix Issues that were closed as part of automated backlog grooming
Projects
None yet
Development

No branches or pull requests

9 participants