Skip to content

Strings

Michael Damatov edited this page Dec 15, 2024 · 1 revision

Strings

Suggests replacing expressions with equivalent expressions that are more readable, or use modern language features, or improve performance. The analyzer doesn't make any suggestions if the current language version doesn't support the replacement or the target framework doesn't contain the target method (or method overload).

In the following examples the text represents any string expression.

Contains

  • bool Contains(string value)
  • bool Contains(string value, StringComparison comparisonType)
Case Suggested replacement When suggested
text.Contains("") true text is not null here and value is a constant empty string
text.Contains("", comparisonType) true text is not null here and value is a constant empty string
text.Contains("a") text.Contains('a') value is a one-character constant string
text.Contains("a", comparisonType) text.Contains('a', comparisonType) value is a one-character constant string

where comparisonType is a StringComparison value.

EndsWith

  • bool EndsWith(char value)
  • bool EndsWith(string value)
  • bool EndsWith(string value, StringComparison comparisonType)
Case Suggested replacement When suggested
text.EndsWith('a') text is [.., 'a'] text is not null here and value is a constant
text.EndsWith(c) text is [.., var lastChar] && lastChar == c text is not null here
text.EndsWith("") true text is not null here and value is a constant empty string
text.EndsWith("", comparisonType) true text is not null here and value is a constant empty string
text.EndsWith("a", StringComparison.Ordinal) text is [.., 'a'] text is not null here, value is a one-character constant string, and comparisonType is Ordinal
text.EndsWith("a", StringComparison.OrdinalIgnoreCase) text is [.., 'a' or 'A'] text is not null here, value is a one-character constant string, and comparisonType is OrdinalIgnoreCase

where c is a char value and comparisonType is a StringComparison value.

IndexOf

  • int IndexOf(char value)
  • int IndexOf(char value, int startIndex)
  • int IndexOf(char value, StringComparison comparisonType)
  • int IndexOf(string value)
  • int IndexOf(string value, int startIndex)
  • int IndexOf(string value, StringComparison comparisonType)
  • int IndexOf(string value, int startIndex, StringComparison comparisonType)
Case Suggested replacement When suggested
text.IndexOf('a') == 0 text is ['a', ..] value is a constant and checked if the result is equal to 0
text.IndexOf(c) == 0 text is [var firstChar, ..] && firstChar == c checked if the result is equal to 0
text.IndexOf('a') != 0 text is not ['a', ..] value is a constant and checked if the result is not equal to 0
text.IndexOf(c) != 0 text is not [var firstChar, ..] ¦¦ firstChar != c checked if result is not equal to 0
text.IndexOf(c) > -1 text.Contains(c) text is not null here and checked if the result is greater than -1
text.IndexOf(c, comparisonType) > -1 text.Contains(c, comparisonType) text is not null here and checked if the result is greater than -1
text.IndexOf(c) >= 0 text.Contains(c) text is not null here and checked if the result is greater than or equal to 0
text.IndexOf(c, comparisonType) >= 0 text.Contains(c, comparisonType) text is not null here and checked if the result is greater than or equal to 0
text.IndexOf(c) != -1 text.Contains(c) text is not null here and checked if the result is not equal to -1
text.IndexOf(c, comparisonType) != -1 text.Contains(c, comparisonType) text is not null here and checked if the result is not equal to -1
text.IndexOf(c) == -1 !text.Contains(c) text is not null here and checked if the result is equal to -1
text.IndexOf(c, comparisonType) == -1 !text.Contains(c, comparisonType) text is not null here and checked if the result is equal to -1
text.IndexOf(c) < 0 !text.Contains(c) text is not null here and checked if the result is less than 0
text.IndexOf(c, comparisonType) < 0 !text.Contains(c, comparisonType) text is not null here and checked if the result is less than 0
text.IndexOf(c, 0) text.IndexOf(c) startIndex is 0
text.IndexOf(s, 0) text.IndexOf(s) startIndex is 0
text.IndexOf(s, 0, comparisonType) text.IndexOf(s, comparisonType) startIndex is 0
text.IndexOf("") 0 text is not null here
text.IndexOf("", comparisonType) 0 text is not null here
text.IndexOf("a") text.IndexOf('a', StringComparison.CurrentCulture) value is a one-character constant string
text.IndexOf("a", comparisonType) text.IndexOf('a', comparisonType) value is a one-character constant string
text.IndexOf(s) == 0 text.StartsWith(s) text is not null here and checked if the result is equal to 0
text.IndexOf(s, comparisonType) == 0 text.StartsWith(s, comparisonType) text is not null here and checked if the result is equal to 0
text.IndexOf(s) != 0 !text.StartsWith(s) text is not null here and checked if result is not equal to 0
text.IndexOf(s, comparisonType) != 0 !text.StartsWith(s, comparisonType) text is not null here and checked if result is not equal to 0
text.IndexOf(s) > -1 text.Contains(s, StringComparison.CurrentCulture) text is not null here and checked if the result is greater than -1
text.IndexOf(s, comparisonType) > -1 text.Contains(s, comparisonType) text is not null here and checked if the result is greater than -1
text.IndexOf(s) >= 0 text.Contains(s, StringComparison.CurrentCulture) text is not null here and checked if the result is greater than or equal to 0
text.IndexOf(s, comparisonType) >= 0 text.Contains(s, comparisonType) text is not null here and checked if the result is greater than or equal to 0
text.IndexOf(s) != -1 text.Contains(s, StringComparison.CurrentCulture) text is not null here and checked if the result is not equal to -1
text.IndexOf(s, comparisonType) != -1 text.Contains(s, comparisonType) text is not null here and checked if the result is not equal to -1
text.IndexOf(s) == -1 !text.Contains(s, StringComparison.CurrentCulture) text is not null here and checked if the result is equal to -1
text.IndexOf(s, comparisonType) == -1 !text.Contains(s, comparisonType) text is not null here and checked if the result is equal to -1
text.IndexOf(s) < 0 !text.Contains(s, StringComparison.CurrentCulture) text is not null here and checked if the result is less than 0
text.IndexOf(s, comparisonType) < 0 !text.Contains(s, comparisonType) text is not null here and checked if the result is less than 0

where c is a char value, s is a string, and comparisonType is a StringComparison value.

Note: In the above example ¦¦ is used instead of || (this wiki limitation)

IndexOfAny

  • int IndexOfAny(char[] anyOf)
  • int IndexOfAny(char[] anyOf, int startIndex)
  • int IndexOfAny(char[] anyOf, int startIndex, int count)
Case Suggested replacement When suggested
text.IndexOfAny([]) -1 text is not null here and anyOf is an empty array
text.IndexOfAny([c]) text.IndexOf(c) anyOf array consists of a single item
text.IndexOfAny([c], startIndex) text.IndexOf(c, startIndex) anyOf array consists of a single item
text.IndexOfAny([c], startIndex, count) text.IndexOf(c, startIndex, count) anyOf array consists of a single item
text.IndexOfAny(['a', 'a']) text.IndexOfAny(['a']) anyOf array contains duplicate constants
text.IndexOfAny(['a', 'a'], startIndex) text.IndexOfAny(['a'], startIndex) anyOf array contains duplicate constants
text.IndexOfAny(['a', 'a'], startIndex, count) text.IndexOfAny(['a'], startIndex, count) anyOf array contains duplicate constants
text.IndexOfAny(chars, 0) text.IndexOfAny(chars) startIndex is 0

where chars is a char array, c is a char value, and startIndex and count are int values.

Join

  • static string Join(string? separator, params object?[] values)
  • static string Join(string? separator, params ReadOnlySpan<object?> values)
  • static string Join<T>(string? separator, IEnumerable<T> values)
  • static string Join(string? separator, IEnumerable<string?> values)
  • static string Join(string? separator, params string?[] value)
  • static string Join(string? separator, string?[] value, int startIndex, int count)
  • static string Join(string? separator, params ReadOnlySpan<string?> value)
  • static string Join(char separator, params object?[] values)
  • static string Join(char separator, params ReadOnlySpan<object?> values)
  • static string Join<T>(char separator, IEnumerable<T> values)
  • static string Join(char separator, params string?[] value)
  • static string Join(char separator, string?[] value, int startIndex, int count)
  • static string Join(char separator, params ReadOnlySpan<string?> value)
Case Suggested replacement When suggested
string.Join(separator, []) "" values is an empty array, collection, or span expression
string.Join(separator, values, 0, 0) "" startIndex is 0 and count is 0
string.Join(separator, [item], 1, 0) "" values consists of a single item, startIndex is 1, and count is 0
string.Join(separator, [item]) item or $"{item}" values consists of a single item
string.Join(separator, [item], 0, 1) item or $"{item}" values consists of a single item, startIndex is 0, and count is 1
string.Join(",", values) string.Join(',', values) separator a one-character constant string
string.Join(",", values, startIndex, count) string.Join(',', values, startIndex, count) separator a one-character constant string

where separator is a string or a char value, values is an array, an IEnumerable<T>, ReadOnlySpan<object?>, or ReadOnlySpan<string?>, and startIndex and count are int values.

LastIndexOf

  • int LastIndexOf(char value, int startIndex)
  • int LastIndexOf(string value)
  • int LastIndexOf(string value, StringComparison comparisonType)
Case Suggested replacement When suggested
text.LastIndexOf(c, 0) -1 text is not null here and startIndex is 0
text.LastIndexOf("") text.Length value is a constant empty string
text.LastIndexOf("", comparisonType) text.Length value is a constant empty string
text.LastIndexOf("a", StringComparison.Ordinal) text.LastIndexOf('a') value is a one-character constant string and comparisonType is Ordinal

where c is a char value and comparisonType is a StringComparison value.

LastIndexOfAny

  • int LastIndexOfAny(char[] anyOf)
  • int LastIndexOfAny(char[] anyOf, int startIndex)
  • int LastIndexOfAny(char[] anyOf, int startIndex, int count)
Case Suggested replacement When suggested
text.LastIndexOfAny([]) -1 text is not null here and anyOf is an empty array
text.LastIndexOfAny([c]) text.LastIndexOf(c) anyOf array consists of a single item
text.LastIndexOfAny([c], startIndex) text.LastIndexOf(c, startIndex) anyOf array consists of a single item
text.LastIndexOfAny([c], startIndex, count) text.LastIndexOf(c, startIndex, count) anyOf array consists of a single item
text.LastIndexOfAny(['a', 'a']) text.LastIndexOfAny(['a']) anyOf array contains duplicate constants
text.LastIndexOfAny(['a', 'a'], startIndex) text.LastIndexOfAny(['a'], startIndex) anyOf array contains duplicate constants
text.LastIndexOfAny(['a', 'a'], startIndex, count) text.LastIndexOfAny(['a'], startIndex, count) anyOf array contains duplicate constants
text.LastIndexOfAny(chars, 0) -1 text is not null here and startIndex is 0
text.LastIndexOfAny(chars, 0, 0) -1 text is not null here, startIndex is 0, and count is 0
text.LastIndexOfAny(chars, 0, 1) -1 text is not null here, startIndex is 0, and count is 1

where chars is a char array, c is a char value, and startIndex and count are int values.

PadLeft

  • string PadLeft(int totalWidth)
  • string PadLeft(int totalWidth, char paddingChar)
Case Suggested replacement When suggested
text.PadLeft(0) text totalWidth is 0
text.PadLeft(0, c) text totalWidth is 0
text.PadLeft(totalWidth, ' ') text.PadLeft(totalWidth) paddingChar is a constant space character

where c is a char value and totalWidth is an int value.

PadRight

  • string PadRight(int totalWidth)
  • string PadRight(int totalWidth, char paddingChar)
Case Suggested replacement When suggested
text.PadRight(0) text totalWidth is 0
text.PadRight(0, c) text totalWidth is 0
text.PadRight(totalWidth, ' ') text.PadRight(totalWidth) paddingChar is a constant space character

where c is a char value and totalWidth is an int value.

Remove

  • string Remove(int startIndex)
  • string Remove(int startIndex, int count)
Case Suggested replacement When suggested
text.Remove(0) "" text is not null here and startIndex is 0
text.Remove(startIndex) text[..startIndex] always
text.Remove(0, count) text[count..] startIndex is 0

where startIndex and count are int value.

Replace

  • string Replace(char oldChar, char newChar)
  • string Replace(string oldValue, string? newValue)
  • string Replace(string oldValue, string? newValue, StringComparison comparisonType)
Case Suggested replacement When suggested
text.Replace('a', 'a') text oldChar and newChar are identical constants
text.Replace("abc", "abc") text oldValue is a constant non-empty string and newValue is a constant string indentical to oldValue
text.Replace("abc", "abc", StringComparison.Ordinal) text oldValue is a constant non-empty string, newValue is a constant string indentical to oldValue, and comparisonType is Ordinal
text.Replace("a", "b") text.Replace('a', 'b') oldValue and newValue are one-character constant strings
text.Replace("a", "b", StringComparison.Ordinal) text.Replace('a', 'b') oldValue and newValue are one-character constant strings and comparisonType is Ordinal

Split

  • string[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None)
  • string[] Split(params char[]? separator)
  • string[] Split(char[]? separator, int count)
  • string[] Split(char[]? separator, StringSplitOptions options)
  • string[] Split(char[]? separator, int count, StringSplitOptions options)
  • string[] Split(string? separator, StringSplitOptions options = StringSplitOptions.None)
  • string[] Split(string? separator, int count, StringSplitOptions options = StringSplitOptions.None)
  • string[] Split(string[]? separator, StringSplitOptions options)
  • string[] Split(string[]? separator, int count, StringSplitOptions options)
Case Suggested replacement When suggested
text.Split(c, 0, options) [] or Array.Empty<string> text is not null here and count is 0
text.Split(s, 0, options) [] or Array.Empty<string> text is not null here and count is 0
text.Split(chars, 0) [] or Array.Empty<string> text is not null here and count is 0
text.Split(chars, 0, options) [] or Array.Empty<string> text is not null here and count is 0
text.Split(stringArray, 0, options) [] or Array.Empty<string> text is not null here and count is 0
text.Split(c, 1, StringSplitOptions.None) [text] or new[] { text } text is not null here, count is 1, and options is None (default)
text.Split(s, 1, StringSplitOptions.None) [text] or new[] { text } text is not null here, count is 1, and options is None (default)
text.Split(chars, 1) [text] or new[] { text } text is not null here, count is 1
text.Split(chars, 1, StringSplitOptions.None) [text] or new[] { text } text is not null here, count is 1, and options is None (default)
text.Split(stringArray, 1, StringSplitOptions.None) [text] or new[] { text } text is not null here, count is 1, and options is None (default)
text.Split("", StringSplitOptions.None) [text] or new[] { text } text is not null here, separator is a constant empty string, and options is None (default)
text.Split("", count, StringSplitOptions.None) [text] or new[] { text } text is not null here, separator is a constant empty string, and options is None (default)
text.Split([""], StringSplitOptions.None) [text] or new[] { text } text is not null here, separator is an array consisting of a single constant empty string, and options is None
text.Split(c, 1, StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, count is 1, and options is TrimEntries
text.Split(s, 1, StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, count is 1, and options is TrimEntries
text.Split(chars, 1, StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, count is 1, and options is TrimEntries
text.Split(stringArray, 1, StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, count is 1, and options is TrimEntries
text.Split("", StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, separator is a constant empty string, and options is TrimEntries
text.Split("", count, StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, separator is a constant empty string, and options is TrimEntries
text.Split([""], StringSplitOptions.TrimEntries) [text.Trim()] or new[] { text.Trim() } text is not null here, separator is an array consisting of a single constant empty string, and options is TrimEntries
text.Split('a', 'a', ...) text.Split('a', ...) separator array contains duplicate constants
text.Split(['a', 'a', ...], count) text.Split(['a', ...], count) separator array contains duplicate constants
text.Split(['a', 'a', ...], options) text.Split(['a', ...], options) separator array contains duplicate constants
text.Split(['a', 'a', ...], count, options) text.Split(['a', ...], count, options) separator array contains duplicate constants
text.Split(["abc", "abc", ...], options) text.Split(["abc", ...], options) separator array contains duplicate constants
text.Split(["abc", "abc", ...], count, options) text.Split(["abc", ...], count, options) separator array contains duplicate constants
text.Split("a", options) text.Split('a', options) separator is a one-character constant string
text.Split("a", count, options) text.Split('a', count, options) separator is a one-character constant string
text.Split(["a", "b", ...], options) text.Split(['a', 'b', ...], options) separator is an array consisting of one-character constant strings
text.Split(["a", "b", ...], count, options) text.Split(['a', 'b', ...], count, options) separator is an array consisting of one-character constant strings

where c is a char value, chars is a char array, s is a string, stringArray is a string array, count is an int value, and options is a StringSplitOptions value.

StartsWith

  • bool StartsWith(char value)
  • bool StartsWith(string value)
  • bool StartsWith(string value, StringComparison comparisonType)
Case Suggested replacement When suggested
text.StartsWith('a') text is ['a', ..] text is not null here and value is a constant
text.StartsWith(c) text is [var firstChar, ..] && firstChar == c text is not null here
text.StartsWith("") true text is not null here and value is a constant empty string
text.StartsWith("", comparisonType) true text is not null here and value is a constant empty string
text.StartsWith("a", StringComparison.Ordinal) text is ['a', ..] text is not null here, value is a one-character constant string, and comparisonType is Ordinal
text.StartsWith("a", StringComparison.OrdinalIgnoreCase) text is ['a' or 'A', ..] text is not null here, value is a one-character constant string, and comparisonType is OrdinalIgnoreCase

where c is a char value and comparisonType is a StringComparison value.

Substring

  • string Substring(int startIndex)
Case Suggested replacement When suggested
text.Substring(0) text startIndex is 0

where startIndex is an int value.

ToString

  • string ToString(IFormatProvider? provider)
Case Suggested replacement When suggested
text.ToString(provider) text always

where provider is an IFormatProvider object.

Trim

  • string Trim(params char[]? trimChars)
Case Suggested replacement When suggested
text.Trim(null) text.Trim() trimChars is null
text.Trim([]) text.Trim() trimChars is an empty array
text.Trim(c, c, ...) text.Trim(c, ...) trimChars contains duplicate constants

where c is a char value.

TrimEnd

  • string TrimEnd(params char[]? trimChars)
Case Suggested replacement When suggested
text.TrimEnd(null) text.TrimEnd() trimChars is null
text.TrimEnd([]) text.TrimEnd() trimChars is an empty array
text.TrimEnd(c, c, ...) text.TrimEnd(c, ...) trimChars contains duplicate constants

where c is a char value.

TrimStart

  • string TrimStart(params char[]? trimChars)
Case Suggested replacement When suggested
text.TrimStart(null) text.TrimStart() trimChars is null
text.TrimStart([]) text.TrimStart() trimChars is an empty array
text.TrimStart(c, c, ...) text.TrimStart(c, ...) trimChars contains duplicate constants

where c is a char value.

💡 Quick-fixes are available.

Current Limitations

  • list patterns might introduce variable with conflicting names

💡 The analyzers can be deactivated in the ReSharper Options dialog.

References