Здравствуйте, Константин Л., Вы писали:
КЛ>я бы написал правило для fxcop, которое бы на IEnumerable.Count выдавало warning. Можно даже в компайлер добавить
Тогда надо чтобы компилятор определял что имеет дело не с ICollection<> иначе будет ругаться почем зря.
Здравствуйте, Юнусов Булат, Вы писали:
ЮБ>Здравствуйте, Константин Л., Вы писали:
КЛ>>я бы написал правило для fxcop, которое бы на IEnumerable.Count выдавало warning. Можно даже в компайлер добавить
ЮБ>Тогда надо чтобы компилятор определял что имеет дело не с ICollection<> иначе будет ругаться почем зря.
если у объекта статический тип IEnumerable<>, я бы заставил ругаться всегда
Здравствуйте, Юнусов Булат, Вы писали:
ЮБ>Здравствуйте, Константин Л., Вы писали:
КЛ>>если у объекта статический тип IEnumerable<>, я бы заставил ругаться всегда
ЮБ>Злые вы, кто нить поставит ворнинги как егоги и будет мучатся — оно тебе надо?
просто count, enumerable & perfomance вещи несовместимые. однако так легко их совместить, не заметив
Здравствуйте, SergASh, Вы писали:
SAS>Интересует человеческий вариант на LINQ-операторах, а не это убожество, приведенное ниже.
Убожество №2:
using System;
using System.Linq;
class Program {
static void Main() {
var digits = new[] { 1, 2, 3 };
var german = new[] { "ein", "zwei", "drei" };
var q = Enumerable
.Repeat(new { de = digits.GetEnumerator(), ge = german.GetEnumerator() }, int.MaxValue)
.Select(_ => _.de.MoveNext() && _.ge.MoveNext() ? new { d = _.de.Current, g = _.ge.Current, e = _ } : null)
.TakeWhile(_ => _ != null)
.Select((_, i) => {
if (i == 0) {
if (_.e.de is IDisposable)
((IDisposable)_.e.de).Dispose();
if (_.e.ge is IDisposable)
((IDisposable)_.e.ge).Dispose();
}
return new { _.d, _.g };
});
foreach (var i in q)
Console.WriteLine(i);
}
}
var digits = new List<int> { 1, 2, 3 };
var german = new List<string> { "ein", "zwei", "drei" };
//...
Сомнения взяли, насчет Dispose() енумераторов на первой итерации.
Как после первой итерации будет выполняться Select к енумераторам, когда они уже будут Dispose'd ???
Массивы возвращают енумератор, который не поддерживает IDisposable, поэтому пример не актуальный.
A>var e = german.GetEnumerator();
A>var c = from d in digits
A> select new { Digit = d, Phrase = e.MoveNext() ? e.Current : null };
A>
S>>Единственная проблема — запрос не вызвать повторно и перечислитель не освободится. A>Да, это проблема.
А так можно от проблемы избавиться, завернув получение енумератора в тело запроса:
var c = from z in Enumerable.Range(1, 1) // это, конечно, загогулина :( let b = german.GetEnumerator()
from Digit in digit
select new { Digit, Phrase = b.MoveNext() ? b.Current : null };
Здравствуйте, SergASh, Вы писали:
SAS>Есть две последовательности одинаковой длины. Как для них построить соединение, которое бы соотносило элементы с одинаковыми индексами? SAS>То есть на входе { 1, 2, 3 }, { "ein", "zwei", "drei" }. А на выходе { { 1, "ein" }, { 2, "zwei" }, { 3, "drei" } }. SAS>Интересует человеческий вариант на LINQ-операторах...
Вот такой вариант получился (спасибо за идею использования .GetEnumerator'a Юнусову Булату):
int[] digit = { 1, 2, 3 };
string[] german = { "qwe", "ads", "zxc" };
var c = from _ in Enumerable.Range(1, 1) // эта кривизна нужна для встраивания в запрос следующего оператораlet e = german.GetEnumerator()
from Digit in digit
select new { Digit, Phrase = e.MoveNext() ? e.Current : null };
foreach (var x in c)Console.WriteLine(x);
// можно использовать многократноforeach (var x in c) Console.WriteLine(x);
1. Только LINQ операторы. Понятно. Масштабируемо для разного количества входных списков.
Только одно выражение (функция ?).
2. Пример устойчив к разной длине списков,
выравнивая длину резульитрующего списка по первому списку
и заполняя хвост второго списка null'ами
3. Можно использовать многогратно без необходимости инициализации енумератора,
т.к. его инициализация завернута внутри запроса.
Здравствуйте, adanov, Вы писали:
A>Сомнения взяли, насчет Dispose() енумераторов на первой итерации. A>Как после первой итерации будет выполняться Select к енумераторам, когда они уже будут Dispose'd ??? A>Массивы возвращают енумератор, который не поддерживает IDisposable, поэтому пример не актуальный.