/// <summary> /// Compares the specified <paramref name="span"/> and <paramref name="other"/> using the specified <paramref name="comparisonType"/>, /// and returns an integer that indicates their relative position in the sort order. /// <param name="span">The source span.</param> /// <param name="other">The value to compare with the source span.</param> /// <param name="comparisonType">One of the enumeration values that determines how the <paramref name="span"/> and <paramref name="other"/> are compared.</param> /// </summary> public static int CompareTo(this ReadOnlySpan <char> span, ReadOnlySpan <char> other, StringComparison comparisonType) { string.CheckStringComparison(comparisonType); switch (comparisonType) { case StringComparison.CurrentCulture: case StringComparison.CurrentCultureIgnoreCase: return(CultureInfo.CurrentCulture.CompareInfo.Compare(span, other, string.GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.InvariantCulture: case StringComparison.InvariantCultureIgnoreCase: return(CompareInfo.Invariant.Compare(span, other, string.GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.Ordinal: if (span.Length == 0 || other.Length == 0) { return(span.Length - other.Length); } return(string.CompareOrdinal(span, other)); default: Debug.Assert(comparisonType == StringComparison.OrdinalIgnoreCase); return(Ordinal.CompareStringIgnoreCase(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length)); } }
public static int Compare(string?strA, int indexA, string?strB, int indexB, int length, StringComparison comparisonType) { CheckStringComparison(comparisonType); if (strA == null || strB == null) { if (object.ReferenceEquals(strA, strB)) { // They're both null return(0); } return(strA == null ? -1 : 1); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); } if (indexA < 0 || indexB < 0) { string paramName = indexA < 0 ? nameof(indexA) : nameof(indexB); throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index); } if (strA.Length - indexA < 0 || strB.Length - indexB < 0) { string paramName = strA.Length - indexA < 0 ? nameof(indexA) : nameof(indexB); throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index); } if (length == 0 || (object.ReferenceEquals(strA, strB) && indexA == indexB)) { return(0); } int lengthA = Math.Min(length, strA.Length - indexA); int lengthB = Math.Min(length, strB.Length - indexB); switch (comparisonType) { case StringComparison.CurrentCulture: case StringComparison.CurrentCultureIgnoreCase: return(CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.InvariantCulture: case StringComparison.InvariantCultureIgnoreCase: return(CompareInfo.Invariant.Compare(strA, indexA, lengthA, strB, indexB, lengthB, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.Ordinal: return(CompareOrdinalHelper(strA, indexA, lengthA, strB, indexB, lengthB)); default: Debug.Assert(comparisonType == StringComparison.OrdinalIgnoreCase); // CheckStringComparison validated these earlier return(Ordinal.CompareStringIgnoreCase(ref Unsafe.Add(ref strA.GetRawStringData(), indexA), lengthA, ref Unsafe.Add(ref strB.GetRawStringData(), indexB), lengthB)); } }
// Provides a more flexible function for string comparison. See StringComparison // for meaning of different comparisonType. public static int Compare(string?strA, string?strB, StringComparison comparisonType) { if (object.ReferenceEquals(strA, strB)) { CheckStringComparison(comparisonType); return(0); } // They can't both be null at this point. if (strA == null) { CheckStringComparison(comparisonType); return(-1); } if (strB == null) { CheckStringComparison(comparisonType); return(1); } switch (comparisonType) { case StringComparison.CurrentCulture: case StringComparison.CurrentCultureIgnoreCase: return(CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.InvariantCulture: case StringComparison.InvariantCultureIgnoreCase: return(CompareInfo.Invariant.Compare(strA, strB, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.Ordinal: // Most common case: first character is different. // Returns false for empty strings. if (strA._firstChar != strB._firstChar) { return(strA._firstChar - strB._firstChar); } return(CompareOrdinalHelper(strA, strB)); case StringComparison.OrdinalIgnoreCase: return(Ordinal.CompareStringIgnoreCase(ref strA.GetRawStringData(), strA.Length, ref strB.GetRawStringData(), strB.Length)); default: throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); } }
public bool EndsWith(string value, StringComparison comparisonType) { if (value is null) { throw new ArgumentNullException(nameof(value)); } if ((object)this == (object)value) { CheckStringComparison(comparisonType); return(true); } if (value.Length == 0) { CheckStringComparison(comparisonType); return(true); } switch (comparisonType) { case StringComparison.CurrentCulture: case StringComparison.CurrentCultureIgnoreCase: return(CultureInfo.CurrentCulture.CompareInfo.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.InvariantCulture: case StringComparison.InvariantCultureIgnoreCase: return(CompareInfo.Invariant.IsSuffix(this, value, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.Ordinal: int offset = this.Length - value.Length; return((uint)offset <= (uint)this.Length && this.AsSpan(offset).SequenceEqual(value)); case StringComparison.OrdinalIgnoreCase: return(this.Length < value.Length ? false : (Ordinal.CompareStringIgnoreCase(ref Unsafe.Add(ref this.GetRawStringData(), this.Length - value.Length), value.Length, ref value.GetRawStringData(), value.Length) == 0)); default: throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); } }