2009-11-19 2 views
2

Каково точное использование AsEnumerable? Изменит ли он неперечислимую коллекцию на перечислимую коллекцию ?. Пожалуйста, дайте мне простой пример.C# - AsEnumerable Пример

ответ

0

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

Я использую это, чтобы я мог использовать LINQ на DataTable

var mySelect = from table in myDataSet.Tables[0].AsEnumerable() 
      where table["myColumn"].ToString() == "Some text" 
      select table; 
+6

Обратите внимание, что это не типичный пример: вы не можете использовать стандартный метод 'AsEnumerable' (найденный в' System.Linq.Enumerable') с помощью 'DataTable', потому что' DataTable' не реализует 'IEnumerable '. 'DataTable' имеет свою собственную определенную версию' AsEnumerable' (найденную в 'System.Data.DataTableExtensions'), которая возвращает обертку' IEnumerable 'вокруг строк таблицы. – LukeH

1

AsEnumerable() преобразует массив (или список или коллекцию) в IEnumerable <T> коллекции.

Для получения дополнительной информации см. http://msdn.microsoft.com/en-us/library/bb335435.aspx.

Из приведенных выше статей:

The AsEnumerable<TSource>(IEnumerable<TSource>) method has no 
effect other than to change the compile-time type of source from a type 
that implements IEnumerable<T> to IEnumerable<T> itself.
8

From the "Remarks" section of the MSDN documentation:

Метод AsEnumerable<TSource> не имеет никакого эффекта , кроме как изменить время компиляции типа источника от типа, который осуществляет IEnumerable<T> до IEnumerable<T> себя.

AsEnumerable<TSource> может быть использован для выбора между реализациями запроса, когда последовательности реализует IEnumerable<T>, но и имеет различный набор методов общественного запроса доступны. Для Например, учитывая общий класс Table , который реализует IEnumerable<T> и имеет свои собственные методы, такие, как Where, Select и SelectMany, вызов Where бы вызвать общественный Where метод Table. Table типа , который представляет собой таблицу базы данных может иметь Where метод, который принимает аргумент предиката как выражение дерево и преобразует дерево в SQL для удаленного выполнения. Если удаленное выполнение не требуется, например, потому что предикат вызывает локальный метод, метод AsEnumerable<TSource> можно использовать, чтобы скрыть пользовательские метод и вместо того, чтобы сделать стандартные операторов запроса доступны.

+0

Нужно немного форматирования, чтобы сделать (<(Of <(TSource)>))), который читается. –

0

AsEnumerable может использоваться только для перечислимых коллекций. Он просто изменяет тип коллекции на IEnumerable<T> для более простого доступа к расширениям IEnumerable.

0

Нет, он не изменяет неперечислимую коллекцию на перечислимую. Что он возвращает вам обратно, как IEnumerable, так что вы можете использовать его в качестве перечислимого. Таким образом, вы можете использовать объект вместе с расширениями IEnumerable и рассматриваться как таковые.

+0

Обычно коллекции перечислимы (я не знаком), то почему я возвращаю перечислимую коллекцию снова AsEnumerable? – 2009-11-19 15:16:03

6

Если вы посмотрите на отражатель:

public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) 
{ 
    return source; 
} 

Это в основном ничего не делает больше, чем вниз литья то, что реализует IEnumerable.

2

никто не говорил об этом по какой-то причине, но заметим, что something.AsEnumerable() эквивалентно (IEnumerable<TSomething>) something. Разница в том, что приведение требует, чтобы тип элементов указывался явно, что, конечно, неудобно. Для меня это основная причина использовать AsEnumerable() вместо актеров.

0

Вот пример кода, который может иллюстрировать правильное объяснение LukeH.

IEnumerable<Order> orderQuery = dataContext.Orders 
    .Where(o => o.Customer.Name == "Bob") 
    .AsEnumerable() 
    .Where(o => MyFancyFilterMethod(o, MyFancyObject)); 

Первый Где Queryable.Where, который транслируется в SQL и запустить в базе данных (o.Customer не загружен в память).

Второе место где Enumerable.Where, которое вызывает метод in-memory с экземпляром чего-то, что я не хочу отправлять в базу данных.

Без метода AsEnumerable, я должен был бы написать это следующим образом:

IEnumerable<Order> orderQuery = 
    ((IEnumerable<Order>) 
    (dataContext.Orders.Where(o => o.Customer.Name == "Bob"))) 
    .Where(o => MyFancyFilterMethod(o, MyFancyObject)); 

Или

IEnumerable<Order> orderQuery = 
    Enumerable.Where(
    dataContext.Orders.Where(o => o.Customer.Name == "Bob"), 
    (o => MyFancyFilterMethod(o, MyFancyObject)); 

ни один из которых хорошо текут вообще.

0
static void Main() 
    { 
     /* 
     "AsEnumerable" purpose is to cast an IQueryable<T> sequence to IEnumerable<T>, 
     forcing the remainder of the query to execute locally instead of on database as below example so it can hurt performance. (bind Enumerable operators instead of Queryable). 

     In below example we have cars table in SQL Server and are going to filter red cars and filter equipment with some regex: 
     */ 
     Regex wordCounter = new Regex(@"\w"); 
     var query = dataContext.Cars.Where(car=> article.Color == "red" && wordCounter.Matches(car.Equipment).Count < 10); 

     /* 
     SQL Server doesn’t support regular expressions therefore the LINQ-to-db providers will throw an exception: query cannot be translated to SQL. 

     TO solve this firstly we can get all cars with red color using a LINQ to SQL query, 
     and secondly filtering locally for Equipment of less than 10 words: 
     */ 

     Regex wordCounter = new Regex(@"\w"); 

     IEnumerable<Car> sqlQuery = dataContext.Cars 
      .Where(car => car.Color == "red"); 
     IEnumerable<Car> localQuery = sqlQuery 
      .Where(car => wordCounter.Matches(car.Equipment).Count < 10); 

     /* 
     Because sqlQuery is of type IEnumerable<Car>, the second query binds to the local query operators, 
     therefore that part of the filtering is run on the client. 

     With AsEnumerable, we can do the same in a single query: 

     */ 
     Regex wordCounter = new Regex(@"\w"); 
     var query = dataContext.Cars 
      .Where(car => car.Color == "red") 
      .AsEnumerable() 
      .Where(car => wordCounter.Matches(car.Equipment).Count < 10); 

     /* 
     An alternative to calling AsEnumerable is ToArray or ToList. 
     */ 
    } 
Смежные вопросы