Skip to content

Commit 10f8a7d

Browse files
committed
Add string.Contains shims
* Use C# 14 extension members to polyfill the required APIs * Remove suppression of CA2249: Consider using 'string.Contains' instead of 'string.IndexOf'
1 parent 171bbb1 commit 10f8a7d

File tree

28 files changed

+63
-62
lines changed

28 files changed

+63
-62
lines changed

src/libraries/Common/src/System/CodeDom/CodeTypeReference.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,7 @@ private void Initialize(string? typeName, CodeTypeReferenceOptions options)
264264
}
265265

266266
// Now see if we have some arity. baseType could be null if this is an array type.
267-
#if NET
268-
if (_baseType != null && _baseType.Contains('`')) // string.Contains(char) is .NetCore2.1+ specific
269-
#else
270-
if (_baseType != null && _baseType.IndexOf('`') != -1) // string.Contains(char) is .NetCore2.1+ specific
271-
#endif
267+
if (_baseType != null && _baseType.Contains('`'))
272268
{
273269
_needsFixup = false;
274270
}

src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,11 @@ internal static int GetKeyValuePair(string connectionString, int currentPosition
403403
return currentPosition;
404404
}
405405

406-
#pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf'. This file is built into libraries that don't have string.Contains(char).
407406
private static bool IsValueValidInternal(string? keyvalue)
408407
{
409408
if (null != keyvalue)
410409
{
411-
return (-1 == keyvalue.IndexOf('\u0000')); // string.Contains(char) is .NetCore2.1+ specific
410+
return !keyvalue.Contains('\u0000');
412411
}
413412
return true;
414413
}
@@ -419,14 +418,13 @@ private static bool IsKeyNameValid([NotNullWhen(true)] string? keyname)
419418
{
420419
#if DEBUG
421420
bool compValue = s_connectionStringValidKeyRegex.IsMatch(keyname);
422-
Debug.Assert(((0 < keyname.Length) && (';' != keyname[0]) && !char.IsWhiteSpace(keyname[0]) && (-1 == keyname.IndexOf('\u0000'))) == compValue, "IsValueValid mismatch with regex");
421+
Debug.Assert((0 < keyname.Length) && (';' != keyname[0]) && !char.IsWhiteSpace(keyname[0]) && !keyname.Contains('\u0000') == compValue, "IsValueValid mismatch with regex");
423422
#endif
424423
// string.Contains(char) is .NetCore2.1+ specific
425-
return ((0 < keyname.Length) && (';' != keyname[0]) && !char.IsWhiteSpace(keyname[0]) && (-1 == keyname.IndexOf('\u0000')));
424+
return (0 < keyname.Length) && (';' != keyname[0]) && !char.IsWhiteSpace(keyname[0]) && !keyname.Contains('\u0000');
426425
}
427426
return false;
428427
}
429-
#pragma warning restore CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf'
430428

431429
#if DEBUG
432430
private static Dictionary<string, string> SplitConnectionString(string connectionString, Dictionary<string, string>? synonyms, bool firstKey)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace System
5+
{
6+
internal static partial class NetStandardShims
7+
{
8+
extension(string @this)
9+
{
10+
public bool Contains(char value)
11+
{
12+
#pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf'
13+
return @this.IndexOf(value) >= 0;
14+
#pragma warning restore CA2249
15+
}
16+
17+
public bool Contains(string value, StringComparison comparisonType)
18+
{
19+
#pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf'
20+
return @this.IndexOf(value, comparisonType) >= 0;
21+
#pragma warning restore CA2249
22+
}
23+
}
24+
}
25+
}

src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)</TargetFrameworks>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
66
<DefineConstants>$(DefineConstants);REGISTRY_ASSEMBLY</DefineConstants>
7-
<NoWarn>$(NoWarn);CA2249</NoWarn>
87
<UseCompilerGeneratedDocXmlFile>false</UseCompilerGeneratedDocXmlFile>
98
</PropertyGroup>
109

src/libraries/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,8 @@ private string QuoteSnippetString(string value)
192192
// If the string is short, use C style quoting (e.g "\r\n")
193193
// Also do it if it is too long to fit in one line
194194
// If the string contains '\0', verbatim style won't work.
195-
#pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf'
196-
if (value.Length < 256 || value.Length > 1500 || (value.IndexOf('\0') != -1)) // string.Contains(char) is .NetCore2.1+ specific
195+
if (value.Length < 256 || value.Length > 1500 || value.Contains('\0'))
197196
return QuoteSnippetStringCStyle(value);
198-
#pragma warning restore CA2249
199197

200198
// Otherwise, use 'verbatim' style quoting (e.g. @"foo")
201199
return QuoteSnippetStringVerbatimStyle(value);

src/libraries/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,7 @@ protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression
862862
string typeName = GetTypeOutput(e.CreateType);
863863
Output.Write(typeName);
864864

865-
#if NET
866865
if (!typeName.Contains('('))
867-
#else
868-
if (typeName.IndexOf('(') == -1)
869-
#endif
870866
{
871867
Output.Write("()");
872868
}

src/libraries/System.CodeDom/src/System.CodeDom.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,8 @@
138138
<Compile Include="$(CommonPath)System\CSharpHelpers.cs" />
139139
<Compile Include="StringExtensions.cs" />
140140
</ItemGroup>
141+
142+
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'netstandard2.1'))">
143+
<Compile Include="$(CommonPath)System\NetStandardShims.String.cs" />
144+
</ItemGroup>
141145
</Project>

src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
5-
<NoWarn>$(NoWarn);CA2249</NoWarn>
65
<IncludeInternalObsoleteAttribute>true</IncludeInternalObsoleteAttribute>
76
<UseCompilerGeneratedDocXmlFile>false</UseCompilerGeneratedDocXmlFile>
87
<IsPackable>true</IsPackable>
@@ -275,6 +274,10 @@
275274
<Compile Include="System\Diagnostics\TraceUtils.cs" />
276275
</ItemGroup>
277276

277+
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'netstandard2.1'))">
278+
<Compile Include="$(CommonPath)System\NetStandardShims.String.cs" />
279+
</ItemGroup>
280+
278281
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
279282
<ProjectReference Include="$(LibrariesProjectRoot)System.Diagnostics.EventLog\src\System.Diagnostics.EventLog.csproj" />
280283
</ItemGroup>

src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/BaseConfigurationRecord.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3082,7 +3082,7 @@ internal static string NormalizeLocationSubPath(string subPath, IConfigErrorInfo
30823082
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_first_character, errorInfo);
30833083

30843084
// do not allow problematic starting characters
3085-
if (InvalidFirstSubPathCharacters.IndexOf(subPath[0]) != -1)
3085+
if (InvalidFirstSubPathCharacters.Contains(subPath[0]))
30863086
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_first_character, errorInfo);
30873087

30883088
// do not allow whitespace at end of subPath, as the OS
@@ -3092,7 +3092,7 @@ internal static string NormalizeLocationSubPath(string subPath, IConfigErrorInfo
30923092
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_last_character, errorInfo);
30933093

30943094
// the file system ignores trailing '.', '\', or '/', so do not allow it in a location subpath specification
3095-
if (InvalidLastSubPathCharacters.IndexOf(subPath[subPath.Length - 1]) != -1)
3095+
if (InvalidLastSubPathCharacters.Contains(subPath[subPath.Length - 1]))
30963096
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_last_character, errorInfo);
30973097

30983098
// combination of URI reserved characters and OS invalid filename characters, minus / (allowed reserved character)
@@ -3205,7 +3205,7 @@ internal static string NormalizeConfigSource(string configSource, IConfigErrorIn
32053205
if (string.IsNullOrEmpty(configSource) || Path.IsPathRooted(configSource))
32063206
throw new ConfigurationErrorsException(SR.Config_source_invalid_format, errorInfo);
32073207

3208-
if (configSource.IndexOf('\\') != -1 || configSource.IndexOf('/') != -1) // string.Contains(char) is .NetCore2.1+ specific
3208+
if (configSource.Contains('\\') || configSource.Contains('/'))
32093209
{
32103210
string newConfigSource = configSource.Replace('\\', '/');
32113211
if (!ConfigPathUtility.IsValid(newConfigSource))

src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationLockCollection.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,7 @@ internal bool DefinedInParent(string name)
219219
}
220220

221221
string parentListEnclosed = "," + _seedList + ",";
222-
if (name.Equals(_ignoreName) ||
223-
#if NET
224-
parentListEnclosed.Contains("," + name + ",", StringComparison.Ordinal))
225-
#else
226-
parentListEnclosed.IndexOf("," + name + ",", StringComparison.Ordinal) >= 0)
227-
#endif
222+
if (name.Equals(_ignoreName) || parentListEnclosed.Contains("," + name + ",", StringComparison.Ordinal))
228223
return true;
229224
return _internalDictionary.Contains(name) &&
230225
(((ConfigurationValueFlags)_internalDictionary[name] & ConfigurationValueFlags.Inherited) != 0);

0 commit comments

Comments
 (0)