Skip to content

Conversation

@SimonZhao888
Copy link
Member

@SimonZhao888 SimonZhao888 commented Jan 7, 2026

Fixes #14187

Root Cause

PropertyGrid.SelectedObjects accepts a covariant array (for example, CustomTypeDescriptor[]), and during subsequent property-merging logic, the internal code treats this array as object?[] and attempts to write elements into it. Because the CLR enforces runtime type checks on covariant arrays, writing an element whose type does not match the underlying array’s actual element type triggers an ArrayTypeMismatchException.
Span’s invariance prevents converting a covariant array directly into Span<object?>, but this is not the fundamental cause of the exception—the root issue is unsafe writes to a covariant array. The GetMergedProperties method returning null is a secondary symptom of the error chain, not the root cause.

Proposed changes

  • Added boundary check for empty array.
  • Created intermediate object?[] arrays to enable proper type covariance.
  • Simplified single-object handling.
  • Added explanatory comments about why this workaround is necessary.

Customer Impact

  • PropertyGrid.SelectedObjects shows correctly grid with typed arrays when PropertySort is NoSort.

Regression?

  • Yes

Risk

  • Min

Screenshots

Before

Before.mp4

After

After.mp4

Test methodology

  • Manually

Test environment(s)

  • .net 11.0.100-alpha.1.25618.104
Microsoft Reviewers: Open in CodeFlow

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a .NET 9/10 regression where PropertyGrid.SelectedObjects displays an empty grid when using typed arrays with PropertySort set to NoSort. The issue stems from Span enforcing exact type matching, which causes ArrayTypeMismatchException when working with typed arrays like ItemTypeDescriptor[].

Key Changes:

  • Added empty array boundary check to prevent null reference issues
  • Introduced intermediate object?[] arrays to work around Span covariance limitations
  • Restructured single-object and multi-object handling logic

@codecov
Copy link

codecov bot commented Jan 7, 2026

Codecov Report

❌ Patch coverage is 65.75342% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.16063%. Comparing base (15506ad) to head (57967f6).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@                 Coverage Diff                 @@
##                main      #14190         +/-   ##
===================================================
+ Coverage   77.15242%   77.16063%   +0.00820%     
===================================================
  Files           3279        3279                 
  Lines         645333      645403         +70     
  Branches       47720       47726          +6     
===================================================
+ Hits          497890      497997        +107     
+ Misses        143757      143717         -40     
- Partials        3686        3689          +3     
Flag Coverage Δ
Debug 77.16063% <65.75342%> (+0.00820%) ⬆️
integration 18.97305% <0.00000%> (-0.01119%) ⬇️
production 52.03420% <30.00000%> (+0.01874%) ⬆️
test 97.40478% <90.69767%> (-0.00082%) ⬇️
unit 49.49544% <30.00000%> (+0.05369%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@KlausLoeffelmann KlausLoeffelmann left a comment

Choose a reason for hiding this comment

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

@SimonZhao888, can you please address the Copilot comments, before I review?

Also, a question:
Could you comment on what the introduction of nullablility regressed and how?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

@SimonZhao888
Copy link
Member Author

@SimonZhao888, can you please address the Copilot comments, before I review?

Also, a question: Could you comment on what the introduction of nullablility regressed and how?

OK, got it!

@SimonZhao888
Copy link
Member Author

Nullable Introduction Regression (What regressed and how)

After introducing nullable annotations, the type signature of SelectedObjects changed from object[] to object?[]. This change affected generic inference and internal handling in the following ways:

Previously, the code assumed SelectedObjects was always a “real object[]” and that writes would not trigger type mismatch issues.
With object?[], covariant arrays (such as CustomTypeDescriptor[]) more easily pass compiler type checks because CustomTypeDescriptor[] can covariantly convert to object?[].
As a result, the runtime now encounters type mismatches during write operations, causing ArrayTypeMismatchException—a scenario that was less likely under the non-nullable signature because the compiler imposed stricter type constraints.

In short, nullable annotations widened the API’s accepted type range, making it easier for covariant arrays to enter the code path and exposing a latent risk of unsafe writes.

Copy link
Member

@ricardobossan ricardobossan left a comment

Choose a reason for hiding this comment

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

All LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-PropertyGrid PropertyGrid and editor related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PropertyGrid.SelectedObjects shows empty grid with typed arrays when PropertySort is NoSort (.NET 9/10 regression)

3 participants