-
Notifications
You must be signed in to change notification settings - Fork 210
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
Kiota should unconditionally generate C# classes with nullable reference types #3944
Comments
Hi @0xced The minimum required version you're quoting from our documentation is for this quick start tutorial, it's not a requirement for all client applications being built. I understand how this can lead to confusions, and I created a dedicated documentation issue That being said, the minimum language version a kiota client requires is CSharp 7.3, and there's not conditional compilation directive for "is CSharp 8.0 or higher", so we use the runtime as an imperfect proxy. (technically somebody could be targeting net8, but lockdown the language to 7.3, although highly improbable) We also don't want to require people changing the default configuration when it's not absolutely necessary. With all that context in mind, we think the current option is the best, although noisy: somebody with a project targeting netFX or netstandard <2.1 is able to generate a client today and use it without any configuration change. CSharp 8 comes with a lot of new features, some of which requires runtime support. We don't want people to start tweaking their configuration, write code, only to notice that specific feature is not fully supported in their context. Our telemetry (from a year ago, when we made the decision) shows that 10% of projects that are created are still under netfx, and that doesn't account for existing projects that are being updated, hence the difficult choice we had to made to keep supporting that segment (it'd have been easier to drop it). Our hope is that by the time we major rev kiota, usage will have dropped, which means we'll be able to clean up a lot of those things, and take advantage of better patterns. (pattern matching, static nullability check, etc....) |
I find it disappointing to have this huge wart in an otherwise high quality generated code. Especially since the fix for the vast minority of users is straightforward, i.e. explicitly setting
This particular feature, as emphasised in the original post, is a compiler feature and does not require runtime support so projects can target .NET Framework and/or .NET Standard < 2.1 without any problem.
Is adding I see it as a very little price to pay to have a tidy generated code. Moreover the IDEs are very good at identifying this issue and even propose one click solutions! In Rider you just have to click on the contextual action and the Is there any chance for this to be reconsidered before a major kiota revision? |
yes
Before we focus on the when (version/timeline), I'd like to get clarity on the what (impact of the change), and the why (reason for it). On the why: could you expand on the reason the sources of the generated code are so important please? (besides maybe simplicity when debugging and stepping through the code) On the what: consider the following scenario:
The evidence would suggest this is a valid scenario, the support policy would prevent us from releasing such a change without a major version. Although I agree this might be a smaller audience (we don't have numbers for people using kiota in netfx projects), it'd still break them unless their lang version is already set to 8 or above in the csproj. It seems the nullable adds a set of NullableContext and Nullable attributes under the hood so the information can be conveyed between assemblies. Although selecting an older framework results in those attribute definitions being emitted at compilation, probably for compatibility reasons. (switch the default drop down to framework) Lastly, even if said "it's ok to break that audience, and have them change their lang version", since C# 8 comes with lots of new features, some of which are not netfx compatible, they might end up writing code that does work at runtime. Do you have evidence that contradicts those conclusions on the impact? |
I agree with the idea that there is a lot of bloat in the generated code, especially if - and I'm just guessing here - most people using Kiota will use it for new projects, and I severely hope (for their sake) that they don't start new projects on a legacy tech stack(.Net Framework) |
As developers we have enough things breaking everyday. I sincerely appreciate your efforts and won't argue further for a breaking change, no matter how small it might look. I'll wait for the next major version and I'll use my fork in the meantime. After all, that's the beauty of open source. I just hope that it will not fall under the radar when the policy service bot will inevitable close this issue. |
Thank you for your understanding. Yes, I'll move this issue into the v2 milestone and remove the tags that result in the bot adding those comments/closing the issues. |
There are bugs all over the place, resulting from the currently weird on/off switching of nullability context all the time. For example, the indexer parameter on endpoints is declared as Therefore, the current state of the generated client is: not nullable aware, except for a few special-cased places. At the places where nullability is turned on, it is often wrong, which is a known issue. Making every property nullable is even worse than a project that is not nullable-aware at all. Because now we need to type thousands of This issue is pretty easy to fix: Just generate all code as if nullable was enabled project-wide, then suppress the resulting warnings from an included |
Thanks for the additional information For reference, here is how indexers are emitted today public UserItemRequestBuilder this[string position]
// ... Which is equivalent to this, assuming nullable is enabled on the project. public UserItemRequestBuilder this[[DisallowNull] string position]
// ... Are you recommending we change it to that instead? #nullable enable
public UserItemRequestBuilder this[string position]
#nullable restore
// ... |
I have the line After adding This matches the expected behavior described at https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts:
|
Thanks for the additional context. |
I'll give you a tip: The only way to solve this reliably for projects with nullable on/off across all target frameworks is to suppress all of the C# nullability warnings (and drop all This still won't turn on the nullable context in generated files. That requires an explicit You can learn a lot by taking a closer look at NSwag. They've solved so many things over the years that are still broken/unintuitive in kiota. |
Because you're asking me to commit the src to version control and aside from being ugly, all that noise quadruples the number of lines being committed and also impacts compiler throughput. That annoys me sufficiently that i'd rather look for a different tool, if it wouldn't be for kiota being the only tool that is seemingly able to correctly parse this openapi definition in question that i'm having to work with. Kiota does go the extra effort of splitting the generated code up into separate files instead of a single |
Currently, Kiota generates C# classes with conditional compilation to use nullable reference types. For example:
That's a lot of noise making the generated code hard to read. Instead, it should look like this:
I know this has been already discussed in #2594 (comment) but I think the conclusion was wrong.
Nullable reference types, introduced in C# 8 are a compiler feature. So it's totally fine to use nullable reference types even when targeting lower than .NET Standard 2.1, such as .NET Standard 2.0 or .NET Framework 4.6.2, 4.7.x etc.
In order to make the code with nullable reference types compile, one simply has to explicitly specify the C# language version to at least 8.0 in the csproj file:
The requirement for nullable reference types to work is the version of the SDK that is used, not the target framework. C# 8 was introduced along with .NET Core 3.0 meaning that it will work with any SDK from 3.0.0 onwards. And, as stated in Kiota documentation, the .NET 8 SDK is required anyway.
The text was updated successfully, but these errors were encountered: