Понять синтаксис linq

Я действительно смущен, чтобы понять его внутреннюю работу Это синтаксис LINQ

string[] test = new test[] { "abc", "", "cd", "", "aa" };
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();

Я путаюсь, где синтаксис, как он управляется. он помещает весь массив в x? если да, то как он управляет значением x null?

или

если нет, тогда тестовые значения массива помещаются один за другим в x?

Ответ 1

Вы должны рассмотреть остальные ответы, они довольно точны, что я хочу показать вам, и, возможно, это поможет вам понять синтаксис, что этот вид запроса может быть фактически представлен в синтаксисе запроса следующим образом:

string[] test=new test[]{"abc","","cd","","aa"};

// this is the equivalent to your code
// added explicit type to make it clearer, it optional
var a = from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x;

если вы знакомы с SQL, этот синтаксис будет легче читать, даже если вы этого не знаете, этот синтаксис более чист.

Когда код скомпилирован, синтаксис запроса автоматически переводится в синтаксис метода С#, чтобы генерировать IL, поэтому, если вы разложите DLL, вы увидите синтаксис метода вместо синтаксиса запроса

Краткое описание этого кода:

  • Как вы видите, была объявлена ​​переменная x, а тип - string. Зачем? потому что ваш массив является массивом строк

  • in test указывает на источник IEnumerable<> для итерации - ваш массив в этом случае

  • where является довольно объяснительным, он просто выбирает все ненулевые строки из вашего массива

  • И, наконец, выбирает, который на самом деле является проекцией данных.

И все это эквивалентно вашему коду

Теперь вы можете спрашивать себя... Когда я должен использовать один синтаксис или другой? Ну, они эквивалентны, но операторы синтаксиса запросов ограничены, что означает, что большинство операций выполняется с синтаксисом метода вместо синтаксиса запроса. То, что я всегда делаю, это попытаться написать код, который легче читать, код легче понять, если он написан синтаксисом запроса.

О синтаксисе метода синтаксис x => ... известен как выражение лямбда, они могут выглядеть странно, если вы впервые работаете с ними, но в конце концов будете любить их.

В основном лямбды - это ярлыки для делегатов, так что вы делаете с:

x => !string.IsNullOrEmpty(x)

Вы создаете анонимный метод, и метод присваивается параметру делегирования. x представляет string variable.

Эта тема очень обширная, чтобы попытаться объяснить ее здесь, но я надеюсь, что это дало вам представление о том, что позади.

Btw вы можете комбинировать синтаксис следующим образом:

// this is the equivalent to your code
// added explicit type to make it clearer, it optional
var a = (from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x).ToArray();

Если вы google LINQ похожи на googling porm lol, веб-сайт страдает от статей LINQ, образцов и т.д.

Хорошей отправной точкой будет 101 образец из Microsoft

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

ИЗМЕНИТЬ

Я попытаюсь подражать методу Where, чтобы вы могли иметь лучший пример выражения лямбда

// this is basically the declaration of one overload of the Where method
// the this in the parameter declaration, indicates this is an extension method which will be available to all IEnumerable<> objects
// the Func<T, bool> is the interesting part, it is basically a delegate (as a reminder, the last parameter of the Func object indicates the type that must be returned, in this case is a bool)
// the delegate is simply a pointer to a function 
public IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{

   ...some logic




   ... yielding back the reuslts
   foreach(var r in res)
   {
      // here is the delegate in action
       if(predicate(r))
           yield return r;
   }
}

Как вы можете видеть, делегат был вызван как функция (делегаты являются указателями на функции) Прикольно, какая функция??? тот, который вы указали в своем коде

  • x => !string.IsNullOrEmpty(x), а x указывает параметр, переданный из метода Where во внешний код, где вы можете его проверить и использовать для фильтрации ваших результатов.

  • x = > является аббревиатурой для объявления делегата

  • ! string.IsNullOrEmpty(x) это тело вашего анонимного метода, и, как вы видите, оно удовлетворяет требованиям Func<T, bool> it возвращает bool (предикат для фильтрации элементов массива), а в качестве параметра он получил общий T, который в этом случае является строкой из вашего массива

Другой способ объявить выражение лямбда:

test = test.Where(
            (string) x =>
            {
                return !string.IsNullOrEmpty(x)
            })
           .ToArray();

С помощью этого синтаксиса легко показать, что они на самом деле являются методами (анонимными методами)

Ответ 2

мы можем отнести утверждение отдельно и рассмотреть части по одному за раз

x => !string.IsNullOrEmpty(x) в основном определяет функцию, подобную приведенной ниже

bool Filter(string x){
   return !string.IsNullOrEmpty(x)
}

и создает предикат на основе этой функции. Предикат - это просто делегат - функция, которую вы можете передать в переменной.

.Where - это метод расширения, который для простоты можно определить

IEnumerable<T> Where<T>(this IEnumerable<T> sequence,Predicate<T> pred){
   foreach(var elem in sequence){
       if(pred(elem)){
          yield return elem;
       }
   }
}

Если бы вы определили функцию как Filter, как указано выше, вместо использования лямбда, ваше утверждение будет выглядеть следующим образом:

test = test.Where(Filter).ToArray(); 

поэтому, вызывая этот метод расширения в вашем массиве и передавая вышеприведенный предикат, вы будете перебирать все элементы в массиве и возвращать все те элементы, которые соответствуют предикату (т.е. те, которые не являются ни нулевыми, ни имеют значение пустого строка)

Наконец, вы вызываете метод расширения .ToArray(), который превращает возвращаемый .Where (a IEnumerable<string>) в массив

Ответ 3

ИЗМЕНИТЬ

Прочитайте эту статью, вы наверняка получите хорошее представление о том, что у вас есть writtnen......

С# 3.0 Новые возможности языка (часть 1)

Новые возможности языка С# 3.0 (часть 2)


из метод extenstion + lambda experssion часть от С# 3.0

здесь в этом коде

test=test.Where(x => !string.IsNullOrEmpty(x)).ToArray();

where - метод расширения

x => !string.IsNullOrEmpty(x) - это выражение lambda, которое является заменой анонимной функции

вся эта функция проверяет каждый элемент массива... то есть выражение lamdaba проверяет, что каждый элемент массива удовлетворяет условию, который записывается и, наконец, ретунирует массив из тех элементов, которые удовлетворяют условию