2012-06-01 3 views
10

Я очень смущен, чтобы понять ее внутренние рабочие Это синтаксис LINQПонимание Linq синтаксиса

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

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

или

если нет, то значения тест массива поместить по одному в х?

+0

http://msdn.microsoft.com/en-us /library/bb397687.aspx – archil

+0

Посмотрите на следующие статьи: ** http: //msdn.microsoft.com/en-us/magazine/cc163400.aspx** и ** http: //daniel.wertheim.se/ 2011/02/07/c-clean-up-your-linq-queries-and-lambda-expressions/** –

+0

x содержит одно индивидуальное значение вашего массива, проверьте мой ответ для получения более подробной информации. – Jupaol

ответ

10

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

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

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

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

При компиляции кода, этот синтаксис запрос автоматически переводится на C# метод синтаксис для того, чтобы сгенерировать IL, так что если вы dissasmbly библиотеку 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's optional 
var a = (from (string)x in test 
     where !string.IsNullOrEmpty(x) 
     select x).ToArray(); 

Если вы Google LINQ, как прибегая к помощи Porm лол веб страдает статьями LINQ, образцы и т.д.

хорошая точка старта были бы 101 образцов из Microsoft

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

EDIT

я буду стараться подражать Где метод, так что вы можете иметь лучший пример лямбда-выражения

// 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; 
    } 
} 

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

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

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

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

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

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

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

2

EDIT

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

C# 3.0 New Language Features (Part 1)

C# 3.0 New Language Features (Part 2)


это от от extenstion method + lambda experssion часть C# 3.0

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

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

where - это метод extesion

x => !string.IsNullOrEmpty(x) - это лямбда expresion, что замена анонимной функции

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

6

можно взять statem лор друг от друга и исследовать кусочки по одному

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 возвращается (IEnumerable<string>) в массив

Смежные вопросы