refactor(DisplayBase): add IsNullable method#8093
Conversation
Reviewer's GuideRefactors nullable-type handling for display-based components by centralizing an IsNullable() helper in DisplayBase and updating multiple components to rely on it, while simplifying clearability logic and improving consistency in how nullable generic value types are treated. The Select-specific reflection-based unit test for IsNullable is removed as part of this refactor. 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 found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/BootstrapBlazor/Components/AutoFill/AutoFill.razor.cs" line_range="244" />
<code_context>
- private bool IsNullable() => !ValueType.IsValueType || NullableUnderlyingType != null;
-
- private bool GetClearable() => IsClearable && !IsDisabled && IsNullable();
+ private bool GetClearable() => IsClearable && !IsDisabled && (!ValueType.IsValueType || IsNullable());
private async Task OnClickItem(TValue val)
</code_context>
<issue_to_address>
**suggestion:** Avoid duplicating null-assignability logic across components
Both `AutoFill` and `SelectBase` now inline `(!ValueType.IsValueType || IsNullable())`. Since this is effectively "can `TValue` be cleared to null", consider a shared helper on the base class (e.g. `protected bool IsNullAssignable() => !ValueType.IsValueType || IsNullable();`) to remove duplication and keep future nullability changes centralized.
Suggested implementation:
```csharp
private bool GetClearable() => IsClearable && !IsDisabled && IsNullAssignable();
```
To fully implement the suggestion and remove duplication:
1. Add a shared helper on the common base class for `AutoFill` and `SelectBase` (e.g. wherever `ValueType` and `IsNullable()` are currently defined):
```csharp
protected bool IsNullAssignable() => !ValueType.IsValueType || IsNullable();
```
2. Update `SelectBase` (or any other components that currently inline `(!ValueType.IsValueType || IsNullable())`) to call `IsNullAssignable()` instead of duplicating the logic.
3. Ensure `IsNullable()` remains implemented in the base class (or in a place accessible to both `AutoFill` and `SelectBase`) so that `IsNullAssignable()` compiles correctly.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| private bool IsNullable() => !ValueType.IsValueType || NullableUnderlyingType != null; | ||
|
|
||
| private bool GetClearable() => IsClearable && !IsDisabled && IsNullable(); | ||
| private bool GetClearable() => IsClearable && !IsDisabled && (!ValueType.IsValueType || IsNullable()); |
There was a problem hiding this comment.
suggestion: Avoid duplicating null-assignability logic across components
Both AutoFill and SelectBase now inline (!ValueType.IsValueType || IsNullable()). Since this is effectively "can TValue be cleared to null", consider a shared helper on the base class (e.g. protected bool IsNullAssignable() => !ValueType.IsValueType || IsNullable();) to remove duplication and keep future nullability changes centralized.
Suggested implementation:
private bool GetClearable() => IsClearable && !IsDisabled && IsNullAssignable();To fully implement the suggestion and remove duplication:
- Add a shared helper on the common base class for
AutoFillandSelectBase(e.g. whereverValueTypeandIsNullable()are currently defined):
protected bool IsNullAssignable() => !ValueType.IsValueType || IsNullable();-
Update
SelectBase(or any other components that currently inline(!ValueType.IsValueType || IsNullable())) to callIsNullAssignable()instead of duplicating the logic. -
Ensure
IsNullable()remains implemented in the base class (or in a place accessible to bothAutoFillandSelectBase) so thatIsNullAssignable()compiles correctly.
There was a problem hiding this comment.
Pull request overview
This PR centralizes nullable value-type detection by introducing a shared IsNullable() helper on DisplayBase<TValue>, and updates multiple components to use it instead of directly checking NullableUnderlyingType.
Changes:
- Add
DisplayBase<TValue>.IsNullable()to encapsulateNullable<T>detection. - Refactor select, radio, validation, datetime picker, and numeric input components to use
IsNullable()in their nullable-specific logic. - Remove a select unit test that was asserting the old (broader) nullability behavior via reflection.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/UnitTest/Components/SelectTest.cs | Removes reflection-based unit test for IsNullable behavior. |
| src/BootstrapBlazor/Components/Validate/ValidateBase.cs | Uses IsNullable() for empty-string parsing and parsing-failure validation gating. |
| src/BootstrapBlazor/Components/SelectGeneric/SelectGeneric.razor.cs | Uses IsNullable() to decide enum placeholder/null-item behavior. |
| src/BootstrapBlazor/Components/Select/SelectBase.cs | Removes local IsNullable and updates clearable logic to use IsNullable() plus reference-type check. |
| src/BootstrapBlazor/Components/Select/Select.razor.cs | Uses IsNullable() to decide enum placeholder/null-item behavior. |
| src/BootstrapBlazor/Components/Radio/RadioListGeneric.razor.cs | Uses IsNullable() to decide auto null-item insertion for nullable enums. |
| src/BootstrapBlazor/Components/Radio/RadioList.razor.cs | Uses IsNullable() to decide auto null-item insertion for nullable enums. |
| src/BootstrapBlazor/Components/InputNumber/BootstrapInputNumber.razor.cs | Uses IsNullable() to decide when to clear the input on blur for nullable types. |
| src/BootstrapBlazor/Components/Display/DisplayBase.cs | Adds the new protected IsNullable() helper (Nullable detection). |
| src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs | Sets AllowNull based on IsNullable(). |
| src/BootstrapBlazor/Components/AutoFill/AutoFill.razor.cs | Removes local IsNullable and updates clearable logic to use IsNullable() plus reference-type check. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8093 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 766 766
Lines 34206 34204 -2
Branches 4697 4695 -2
=========================================
- Hits 34206 34204 -2
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 #8092
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Introduce a shared nullable-type check in DisplayBase and update consumers to use it.
Enhancements:
Tests: