C # - AsEnumerable Пример

2

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

Теги:
enumeration

9 ответов

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<T> . DataTable имеет свою собственную конкретную версию AsEnumerable (находится в System.Data.DataTableExtensions ), которая возвращает оболочку IEnumerable<T> вокруг строк таблицы.
8

В разделе "Замечания" документации MSDN:

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

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

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

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

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

В основном он ничего не делает, кроме того, что выпускаете что-то, что реализует IEnumerable.

3

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

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.
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.
        */
    }
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

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

  • 0
    Обычно коллекции являются Enumerable (я не знаком), тогда почему я возвращаю перечислимую коллекцию снова как AsEnumerable?
0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню