LasyList работает только с источником IQueryable . Это реализация IList , которая работает путем заполнения частного списка всеми результатами из указанного IQueryable . Инициализация происходит при первом обращении к любому из членов IList .
Пример использования будет
var myList = new LazyList(products.Where(p => p.Name.StartsWith("T"));
//initialization occurs here
Console.Write(myList.Count);
Класс System.Lazy работает с любым типом и не ограничивается IQueryable . Ленивая инициализация происходит при первом обращении к свойству Lazy .Value .
Пример использования будет
var lazyString = new Lazy(() => "Hello world");
//initialization occurs here
Console.Write(lazyString.Value);
Мы могли бы переписать пример LazyList для использования Lazy следующим образом:
var myList = new Lazy(() => products.Where(p => p.Name.StartsWith("T").ToList());
//initialization occurs here
Console.Write(myList.Value.Count);
Вкратце: LazyList работает только с IQueryable , Lazy работает с любым типом.
LazyList предназначен для конкретного случая использования, когда вы хотите, чтобы результаты IQueryable представляли собой список , но вы не хотите, чтобы оценка производилась до тех пор, пока вы ее не используете.
ОБНОВЛЕНИЕ, чтобы ответить на расширенный вопрос:
Вы бы порекомендовали одно поверх другого, если бы я хотел работать с IQueryable в виде списка ?
Я предполагаю, что, поскольку Lazy находится в структуре сейчас, это более безопасная ставка для будущей поддержки и ремонтопригодности?
Лично я бы тоже не использовал. Если у вас есть IQueryable, я бы сохранил его как IQueryable, чтобы максимизировать вашу гибкость. Сохраняя IQueryable, вы по-прежнему получаете доступ к LINQ для понимания запросов SQL (пока контекст еще жив).
Например, если вы вызываете .ToList () для IQueryable, вы просите LINQ to SQL выбрать все столбцов из целевой таблицы и гидрировать все результатов (это может быть очень дорого, особенно если у вас есть тысячи результатов). Это будет переведено в нечто вроде «SELECT * FROM MyTable».
Если вы вызываете .Count () в IQueryable, вы запрашиваете LINQ to SQL, чтобы просто получить количество результатов, это будет преобразовано в нечто вроде «SELECT COUNT (*) FROM MyTable». Делать это гораздо эффективнее, чем увлажнять все результаты, а затем подсчитывать их, особенно если вас интересует только число!
Использование .Where () в IQueryable LINQ to SQL добавит ваши условия к предложению WHERE в запросе SQL. Это означает, что вы будете извлекать данные только из интересующего вас SQL-кода, а не гидрировать результаты, которые вы не собираетесь использовать.
Видите ли, поддерживая IQueryable, вы делаете вещи более гибкими для себя. В большинстве случаев это даст вам лучшую производительность, чем увлажнение всего набора результатов.
Если я хочу использовать сильный тип вместо анонимного (var) типа, будут ли следующие операторы функционально эквивалентными?
Lazy<List<Product>> products = new Lazy<List<Product>>();
LazyList<Product> products = new LazyList<Product>();
Я думаю, что вы получаете анонимный ввод в заблуждение с неявным набором. Переменная, объявленная с использованием ключевого слова var, неявно вводится в соответствии с типом, который ей назначен. Это строго типизированный и поэтому не может быть изменено после первоначального назначения.
Два утверждения не являются функционально эквивалентными. LazyList - это IList , тогда как Lazy > - это оболочка, содержащая List . Поскольку вы особенно заинтересованы в работе с отложенным оценочным списком, я бы сказал, что LazyList , вероятно, более конкретен для ваших целей.
Вы должны спросить себя, действительно ли вам нужен фактический Список продуктов. Если у меня нет веских причин для создания настоящего Списка, я бы придерживался IQueryable.