Guard newer APIs to preserve netstandard2.0 compatibility - #140
Conversation
Co-authored-by: wforney <[email protected]>
Co-authored-by: wforney <[email protected]>
Co-authored-by: wforney <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR restores SharedCode.Core’s multi-target compatibility (notably netstandard2.0) by adding narrow preprocessor guards around newer framework-only APIs, keeping optimized implementations on modern TFMs while providing older-safe fallbacks where required.
Changes:
- Guarded
EnumerableExtensions.IsNotNullOrEmptyto useTryGetNonEnumeratedCountonly on supported TFMs. - Updated
BufferedWriterasync flush paths to use cancellableTextWriter.WriteAsync/FlushAsyncoverloads where available, with fallbacks for older targets. - Adjusted
DataReaderExtensions.ToDelimitedstring comparison/replace usage to avoid newer overloads onnetstandard2.0.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| SharedCode.Core/Linq/EnumerableExtensions.cs | Adds a TFM guard so TryGetNonEnumeratedCount is only used when available. |
| SharedCode.Core/IO/BufferedWriter.cs | Uses cancellable async TextWriter overloads on newer TFMs with fallback async write/flush behavior on older TFMs. |
| SharedCode.Core/Data/DataReaderExtensions.cs | Introduces framework-specific string-search/replace paths to preserve netstandard2.0 compatibility. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
SummarySummary
CoverageSharedCode.Core - 27.4%
SharedCode.Core.Tests - 98.1%
SharedCode.Data - 8.3%
SharedCode.Data.Tests - 100%
|
…bility Co-authored-by: wforney <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
SharedCode.Core/Data/DataReaderExtensions.cs:4
System.Globalizationis already provided via the project’s global usings (SharedCode.Core/Core.csproj includes it), so this conditionalusingblock is redundant and adds extra preprocessor complexity. Removing it keeps the file simpler without changing behavior.
#if !(NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER)
using System.Globalization;
#endif
Co-authored-by: wforney <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
SharedCode.Core/Data/DataReaderExtensions.cs:99
- Same nullable-conditional issue here:
value?.IndexOf(separator, ...) >= 0evaluates tobool?and won't compile in anif. Useis >= 0(or coalesce) sonullbecomesfalse.
// If separator is in value, ensure it is put in double quotes.
if (value?.IndexOf(separator, StringComparison.Ordinal) >= 0)
{
value = $"\"{value}\"";
SharedCode.Core/Data/DataReaderExtensions.cs:87
value?.IndexOf(...) >= 0produces a nullablebool?(because of the null-conditional), which cannot be used directly in anifcondition and will fail to compile. Use a relational pattern (is >= 0) (or coalesce) sonullis treated asfalsewithout producingbool?.
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
if (value?.IndexOf('"', StringComparison.Ordinal) >= 0)
#else
if (value?.IndexOf('"') >= 0)
#endif
SharedCode.Corestill targetsnetstandard2.0, but a few call sites had drifted to newer framework-only APIs. This change restores compatibility by keeping newer implementations on modern TFMs and using older-safe fallbacks where required.String API compatibility
stringcomparison overload assumptions inDataReaderExtensionswith framework-specific paths.netstandard2.0.Async
TextWriterfallback behaviorBufferedWriterto use cancellableWriteAsync(..., CancellationToken)/FlushAsync(CancellationToken)where available.Enumeration path for older frameworks
EnumerableExtensions.IsNotNullOrEmptyto useTryGetNonEnumeratedCountonly on supported TFMs.netstandard2.0via the existing enumeration-based check.Conditional framework split
#ifguards instead of broad refactors so newer TFMs still take the optimized/runtime-native code paths.Example of the compatibility pattern used: