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

JSInterop: Enable returning null for a nullable value type #60850

Merged

Conversation

Regenhardt
Copy link
Contributor

@Regenhardt Regenhardt commented Mar 10, 2025

JSInterop: Enable returning null for a nullable value type

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Summary of the changes (Less than 80 chars)

Description

When a result value is null, and the return type is a nullable value type, Convert.ChangeType throws instead of returning the null value, so in case off null this now uses null directly.

Fixes #30366

When a result value is null, and the return type is a nullable value type, Convert.ChangeType throws instead of returning the null value.

dotnet#30366
@Regenhardt Regenhardt requested a review from a team as a code owner March 10, 2025 16:03
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Mar 10, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Mar 10, 2025
@Regenhardt
Copy link
Contributor Author

Pushed a draft of what I wanted the tests to look like, gotta figure out the test fixture stuff too.

@Regenhardt Regenhardt force-pushed the feature/null-value-type-from-js-runtime branch from 6f7d836 to 2dad3d3 Compare March 10, 2025 22:08
@Regenhardt
Copy link
Contributor Author

Regenhardt commented Mar 10, 2025

Ok I kinda figured out how the tests are supposed to work. Just have to install jdk now tomorrow to test locally.

@Regenhardt Regenhardt force-pushed the feature/null-value-type-from-js-runtime branch from 2dad3d3 to fe68842 Compare March 12, 2025 22:32
@Regenhardt Regenhardt force-pushed the feature/null-value-type-from-js-runtime branch from fe68842 to 0a86864 Compare March 13, 2025 15:33
@Regenhardt
Copy link
Contributor Author

Figured it out, tests are green now.

@Regenhardt
Copy link
Contributor Author

Alternative: use result == default instead of result == null && default(T) == null as it might be slightly faster?

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Mar 21, 2025
@Regenhardt
Copy link
Contributor Author

Ready for review.

@@ -89,7 +89,9 @@ public void SetResult(object tcs, object? result)
// If necessary, attempt a cast
var typedResult = result is T resultT
? resultT
: (T)Convert.ChangeType(result, typeof(T), CultureInfo.InvariantCulture)!;
: result == null && default(T) == null // ChangeType can't convert null to value types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems OK to me.

@oroztocil please review

Copy link
Contributor

@hez2010 hez2010 Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why default(T) == null instead of typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>)?
GetGenericTypeDefinition is an intrinsic that will be folded by the compiler, see dotnet/runtime#103528.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>)

This seems like a better option to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hez2010 I didn't know about intrinsics and folding, and honestly still don't entirely understand it. I changed it to check for the generic type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and honestly still don't entirely understand it

The git is able to detect that the expression will be constant for a given T and it's able to optimize it entirely when it generates the machine code for a given T. For example, if you have something like T = int, it's able to know that the condition will always evaluate to false and it can then use that information to simplify the check (and in this case, unconditionally select one branch or another))

@javiercn javiercn added the pr: pending author input For automation. Specifically separate from Needs: Author Feedback label Apr 9, 2025
Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should go with the alternative implementation that @hez2010 suggested.

@Regenhardt
Copy link
Contributor Author

I'm back from vacation and updated the branch, ready for review.

@javiercn javiercn enabled auto-merge (squash) April 10, 2025 13:56
@javiercn javiercn merged commit 0fe4e4c into dotnet:main Apr 10, 2025
27 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 10.0-preview4 milestone Apr 10, 2025
@Regenhardt Regenhardt deleted the feature/null-value-type-from-js-runtime branch April 10, 2025 14:53
@javiercn
Copy link
Member

@Regenhardt thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components community-contribution Indicates that the PR has been added by a community member pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun pr: pending author input For automation. Specifically separate from Needs: Author Feedback
Projects
None yet
Development

Successfully merging this pull request may close these issues.

jsRuntime.InvokeAsync can't return null as Nullable<Guid>
5 participants