public int LastIndexOf(string value, int startIndex, int count, StringComparison comparisonType) { if (value == null) { throw new ArgumentNullException(nameof(value)); } // Special case for 0 length input strings if (this.Length == 0 && (startIndex == -1 || startIndex == 0)) { return((value.Length == 0) ? 0 : -1); } // Now after handling empty strings, make sure we're not out of range if (startIndex < 0 || startIndex > this.Length) { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); } // Make sure that we allow startIndex == this.Length if (startIndex == this.Length) { startIndex--; if (count > 0) { count--; } } // 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0. if (count < 0 || startIndex - count + 1 < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count); } // If we are looking for nothing, just return startIndex if (value.Length == 0) { return(startIndex); } switch (comparisonType) { case StringComparison.CurrentCulture: case StringComparison.CurrentCultureIgnoreCase: return(CultureInfo.CurrentCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.InvariantCulture: case StringComparison.InvariantCultureIgnoreCase: return(CompareInfo.Invariant.LastIndexOf(this, value, startIndex, count, GetCaseCompareOfComparisonCulture(comparisonType))); case StringComparison.Ordinal: case StringComparison.OrdinalIgnoreCase: return(CompareInfo.LastIndexOfOrdinal(this, value, startIndex, count, GetCaseCompareOfComparisonCulture(comparisonType) != CompareOptions.None)); default: throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType)); } }