如果我理解你的问题,那就是要在字符串中两个字符的索引之间获取最小的索引,但问题在于如果只有其中一个存在,那么返回另一个的索引,因为它是
-1
。
解决这个问题的一种方法是在第一个字符串中测试
-1
,然后决定如何处理第二个字符串:
public static int IndexOf (this string s, char a, char b) => s.IndexOf(a) == -1
// If it's not in 'a', return its index in 'b'
? s.IndexOf(b)
: s.IndexOf(b) == -1
// Else if it's not in 'b', return its index in 'a'
? s.IndexOf(a)
// Otherwise, return the smallest index between 'a' and 'b'
: Math.Min(s.IndexOf(a), s.IndexOf(b));
然而,这个扩展方法存在问题!!
由于从char
到int
有一个隐式转换,这个方法将被IndexOf
的本地重载隐藏,该方法接受一个char
和一个int
,返回"指定字符在指定位置之后第一次出现的零基索引。"
我认为这是因为本地方法在任何扩展方法被评估之前都会被评估和选择(如果有隐式匹配),但我可能错了。
为了解决这个问题,我们可以简单地给这个方法取一个不同的名字:
public static int IndexOfFirst (this string s, char a, char b) => s.IndexOf(a) == -1
? s.IndexOf(b)
: s.IndexOf(b) == -1
? s.IndexOf(a)
: Math.Min(s.IndexOf(a), s.IndexOf(b));
此外,我们可以利用一个
params
参数来让这个方法处理从中找到第一个索引的
0
到多个字符。
public static int IndexOfFirst(this string s, params char[] args) =>
(args?.Any(arg => s.IndexOf(arg) > -1)).GetValueOrDefault()
? args.Select(arg => s.IndexOf(arg))
.Where(index => index > -1)
.Min()
: -1;