string.Contains как предикат не вызов функции?

Я нашел этот образец кода на SO (не могу вспомнить, откуда:/), что позволило мне проверить аргументы линейного кода при запуске приложения:

if (e.Args.Length == 0 || e.Args.Any("-show".Contains))
{
  //show interface...
}

Я просто не могу понять, как "-show".Contains работы. И если есть какая-либо разница с (классическим) x => x.Contains('"-show") (за исключением очевидного усиления ввода).

Работает как шарм, но я хотел бы понять, почему, я чувствую, что происходит что-то большое.

Ответы

Ответ 1

Это:

.Any("-show".Contains)

в основном сокращает это:

.Any(s => "-show".Contains(s))

Any метод принимает делегат в качестве параметра, и вы можете создать этот делегат несколькими способами. Первый фрагмент использует группу методов, а второй - Lambda.

Это не очень точно сказать, что первое является сокращением для второго, потому что группы методов предшествуют Lambdas, но если вы думаете в терминах Lambdas при вызове методов LINQ, таких как Any то это действительно так.

Ответ 2

Как уже сказал @jmcilhiney, это сокращает:

.Any(s => "-show".Contains(s))

Contains функцию, принимающую 1 параметр, который имеет строку типа (и возвращает логическое значение). Any() в этом случае хочет функцию, которая нуждается в 1 параметре, который является строкой и возвращает логическое значение. Таким образом, вместо добавления дополнительного лямбда - warapper s=>, вы можете сразу вернуться .Contains

С технической точки зрения это:

Func<string, boolean> //1 param string, output: boolean

Обратите внимание, что этот код соответствует любому аргументу, который является частью -show

таким образом, любой из следующих аргументов соответствует!

-show
-s
sh
ow
h
w
// etc..

Ответ 3

Any() ожидает делегата Func<TSource, bool>. Таким образом, любая функция, которая возвращает bool и принимает аргумент, который имеет тот же тип, что и элементы коллекции (string в вашем случае), может применяться. Это может быть существующая функция или выражение лямбда.

Подпись String.Contains - это

bool Contains(string s)

Вот почему вы можете передать его Any()

Ответ 4

Эквивалентом будет x => "-show".Contains(x) а не то, что вы показали.

После этого вы поймете, что все, что вы делаете, вводя лямбда на основе x - это создать функцию, принимающую один string аргумент, и вернуть bool и обернуть функцию, которая принимает одну string и возвращает bool. Там нет необходимости в обертке.