refactor(DisplayBase): optimize nullable data types#8091
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideRefactors nullable type handling in DisplayBase and dependent components by caching the nullable underlying type per closed generic and consistently using the computed ValueType, plus minor documentation cleanups in TypeExtensions. File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Changing
NullableUnderlyingTypefrom an instance property to aprotected static readonlyfield is a breaking change for any subclasses that were setting it; consider either keeping a (possibly obsolete) setter or clearly routing all subclass customization throughValueTypeinstead so derivations aren’t silently broken. - Now that
ValueTypeis the canonical non-nullable type forTValue, it may be worth tightening remaining call sites that still manually combineNullableUnderlyingType ?? typeof(TValue)to useValueTypeconsistently, to avoid future divergence or misuse of the two concepts.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Changing `NullableUnderlyingType` from an instance property to a `protected static readonly` field is a breaking change for any subclasses that were setting it; consider either keeping a (possibly obsolete) setter or clearly routing all subclass customization through `ValueType` instead so derivations aren’t silently broken.
- Now that `ValueType` is the canonical non-nullable type for `TValue`, it may be worth tightening remaining call sites that still manually combine `NullableUnderlyingType ?? typeof(TValue)` to use `ValueType` consistently, to avoid future divergence or misuse of the two concepts.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR refactors DisplayBase<TValue> and related generic components to avoid repeated reflection when working with nullable generic value types by caching the nullable underlying type and reusing the computed effective value type.
Changes:
- Cache
Nullable.GetUnderlyingType(typeof(TValue))once per closed genericDisplayBase<TValue>via a static field. - Reuse
ValueTypeinRadioList*,BootstrapInputNumber, andMultiSelectinstead of recomputingNullableUnderlyingType ?? typeof(TValue). - Improve English XML documentation in
TypeExtensions.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/BootstrapBlazor/Extensions/TypeExtensions.cs | Improves English XML doc strings for type helper methods. |
| src/BootstrapBlazor/Components/Select/MultiSelect.razor.cs | Uses cached ValueType when resolving the inner type for enum item generation. |
| src/BootstrapBlazor/Components/Radio/RadioListGeneric.razor.cs | Reuses ValueType for enum detection/item generation. |
| src/BootstrapBlazor/Components/Radio/RadioList.razor.cs | Reuses ValueType for enum detection and parsing logic. |
| src/BootstrapBlazor/Components/InputNumber/BootstrapInputNumber.razor.cs | Uses ValueType for decimal-type detection. |
| src/BootstrapBlazor/Components/Display/DisplayBase.cs | Caches nullable underlying type statically and updates nullable-type handling documentation. |
Comments suppressed due to low confidence (1)
src/BootstrapBlazor/Components/Display/DisplayBase.cs:42
- The XML doc for ValueType still says it represents the "nullable type" of TValue, but ValueType is used throughout as the effective value type (i.e., NullableUnderlyingType ?? typeof(TValue)). Updating the doc would make the new refactor (reusing ValueType instead of recomputing) clearer.
/// <summary>
/// <para lang="zh">获得/设置 泛型参数 TValue 可为空类型 Type 实例</para>
/// <para lang="en">Gets or sets Generic Parameter TValue Nullable Type Instance</para>
/// </summary>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// <summary> | ||
| /// <para lang="zh">获得/设置 泛型参数 TValue 可为空类型 Type 实例,为空时表示类型不可为空</para> | ||
| /// <para lang="en">Gets or sets Generic Parameter TValue Nullable Type Instance. Null means type is not nullable</para> | ||
| /// <para lang="zh">获得 泛型参数 TValue 可为空类型 Type 实例,为空时表示类型不可为空</para> | ||
| /// <para lang="en">Gets the underlying type of <typeparamref name="TValue"/> when it is <see cref="Nullable{T}"/>; otherwise <see langword="null"/>.</para> | ||
| /// </summary> |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8091 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 766 766
Lines 34207 34206 -1
Branches 4702 4697 -5
=========================================
- Hits 34207 34206 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Link issues
fixes #8090
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Cache the nullable underlying type for generic display components and reuse the computed value type across consumers to avoid repeated reflection.
Enhancements: