You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve ToString() method excluding BiDi (friendly for AOT)
🔄 Types of changes
Cleanup (formatting, renaming)
Bug fix (backwards compatible)
PR Type
Enhancement, Bug fix
Description
Convert BrowsingContext to record type with ID-based equality
Implement consistent equality and hash code across BiDi DTOs
Add PrintMembers() for AOT-friendly string representation
Standardize ID comparison using ordinal string comparison
Diagram Walkthrough
flowchart LR
A["BiDi DTO Classes"] -->|Convert to record| B["BrowsingContext record"]
A -->|Add equality methods| C["Equals by ID only"]
A -->|Implement PrintMembers| D["AOT-friendly ToString"]
C -->|Use StringComparer.Ordinal| E["Consistent comparison"]
nvborisenko
changed the title
[dotnet] [bidi] BrowsingCoontext type as record with equality
[dotnet] [bidi] BrowsingContext type as record with equality
Dec 6, 2025
Objective: To create a detailed and reliable record of critical system actions for security analysis and compliance.
Status: No audit logs: The new equality, hash code, and PrintMembers changes introduce no logging for critical actions, but it's unclear whether such logging is applicable for these DTOs without broader context.
Referred Code
publicTask<Subscription>OnNavigationCommittedAsync(Func<NavigationInfo,Task>handler,ContextSubscriptionOptions?options=null){returnBiDi.BrowsingContext.OnNavigationCommittedAsync(handler,options.WithContext(this));}publicboolEquals(BrowsingContext?other){returnotheris not null&&string.Equals(Id,other.Id,StringComparison.Ordinal);}publicoverrideintGetHashCode(){returnIdis not null?StringComparer.Ordinal.GetHashCode(Id):0;}// Includes Id only for brevityprivateboolPrintMembers(StringBuilderbuilder){builder.Append($"Id = {Id}");returntrue;}
To reduce code duplication, create an abstract base record to centralize the identical Id-based equality, hash code, and PrintMembers logic currently repeated across nine different record types.
publicboolEquals(UserContext?other){returnotheris not null&&string.Equals(Id,other.Id,StringComparison.Ordinal);}publicoverrideintGetHashCode(){returnIdis not null?StringComparer.Ordinal.GetHashCode(Id):0;}
...(clipped 6lines)
publicboolEquals(BrowsingContext?other){returnotheris not null&&string.Equals(Id,other.Id,StringComparison.Ordinal);}publicoverrideintGetHashCode(){returnIdis not null?StringComparer.Ordinal.GetHashCode(Id):0;}
...(clipped 6lines)
Solution Walkthrough:
Before:
// In UserContext.cs, Collector.cs, Intercept.cs, etc.publicsealedrecordUserContext{internalstringId{get;}// ... other properties and methodspublicboolEquals(UserContext?other){returnotheris not null&&string.Equals(Id,other.Id,StringComparison.Ordinal);}publicoverrideintGetHashCode(){returnIdis not null?StringComparer.Ordinal.GetHashCode(Id):0;}privateboolPrintMembers(StringBuilderbuilder){builder.Append($"Id = {Id}");returntrue;}}
After:
// New base recordpublicabstractrecordBiDiEntity(stringId){publicvirtualboolEquals(BiDiEntity?other){returnotheris not null&&string.Equals(Id,other.Id,StringComparison.Ordinal);}publicoverrideintGetHashCode()=>StringComparer.Ordinal.GetHashCode(Id??string.Empty);protectedvirtualboolPrintMembers(StringBuilderbuilder){builder.Append($"Id = {Id}");returntrue;}}// In UserContext.cs, Collector.cs, Intercept.cs, etc.publicsealedrecordUserContext(stringId):BiDiEntity(Id);
Suggestion importance[1-10]: 9
__
Why: This suggestion correctly identifies significant code duplication across nine files and proposes a valid architectural improvement to centralize common logic, enhancing maintainability and adhering to the DRY principle.
High
Learned best practice
Centralize equality helpers
These equality and PrintMembers implementations are duplicated across multiple record types; extract a shared helper/base to centralize the logic and prevent drift.
-public bool Equals(BrowsingContext? other)-{- return other is not null && string.Equals(Id, other.Id, StringComparison.Ordinal);-}+// Example: use a shared static helper+public bool Equals(BrowsingContext? other) => EqualityHelpers.IdEquals(Id, other?.Id);-public override int GetHashCode()-{- return Id is not null ? StringComparer.Ordinal.GetHashCode(Id) : 0;-}+public override int GetHashCode() => EqualityHelpers.IdHashCode(Id);-// Includes Id only for brevity-private bool PrintMembers(StringBuilder builder)-{- builder.Append($"Id = {Id}");- return true;-}+private bool PrintMembers(StringBuilder builder) => EqualityHelpers.AppendId(builder, Id);
Apply / Chat
Suggestion importance[1-10]: 6
__
Why:
Relevant best practice - Replace ad-hoc duplication with shared helpers/utilities to reduce repetition and centralize logic.
Low
General
Simplify GetHashCode implementation for conciseness
Simplify the GetHashCode implementation by using the null-coalescing operator (??) with string.Empty for null Id values, instead of a ternary conditional check.
public override int GetHashCode()
{
- return Id is not null ? StringComparer.Ordinal.GetHashCode(Id) : 0;+ return StringComparer.Ordinal.GetHashCode(Id ?? string.Empty);
}
Apply / Chat
Suggestion importance[1-10]: 3
__
Why: The suggestion improves code conciseness by using the null-coalescing operator, which is a valid stylistic improvement, but it has a very low impact on the overall code quality.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
💥 What does this PR do?
🔄 Types of changes
PR Type
Enhancement, Bug fix
Description
Convert
BrowsingContextto record type with ID-based equalityImplement consistent equality and hash code across BiDi DTOs
Add
PrintMembers()for AOT-friendly string representationStandardize ID comparison using ordinal string comparison
Diagram Walkthrough
File Walkthrough
9 files
Convert to record with ID-based equalityAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembersAdd ID-based equality and PrintMembers