Кстати-кстати. Тут не все так просто. Это один из тонких моментов в LINQ. Первый вариант решения, который приходит на ум, - забить на LINQ и воспользоваться старым-добрым foreach. В этом случае за O(n) операций можно найти необходимый элемент. Чем не вариант? Да тем, что после LINQ ну очень не хочется писать подобный "низкоуровневый" перебор. Если говорить о LINQ решениях этой проблемы, то можно, например, отсортировать список по убыванию и взять первый элемент. Естественно, производительность в этом случае не выдерживает никакой критики (O log n операций и куча понапрасну использованной памяти). Если показать такое решение программисту со старой закалкой, его, наверное, инфаркт хватит  Второй LINQ-вариант - использовать код, подобный тому, который написал HalkaR. Только вот, честно говоря, меня удивило, что
Цитата(Bonus @ 1.7.2008, 11:13 ) | | хм... сработало, спасибо smile |
Ведь этот код возвращает не Point, а коллекцию Point'ов. У меня такой код даже не комплируется (Resharper сразу ругается):
| Цитата | Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Drawing.Point>' to 'System.Drawing.Point'
|
Кстати в том кусочке кода еще одна ошибка: переменная p объявляется два раза. Такое не скомпилируется. И выражение
надо заменить на что-нибудь вроде
| Код | points.Max(p1 => p1.X)
|
Ну это так, мелочи: HalkaR просто опечатался. Чтобы заставить этот код делать именно то, что нужно, просто добавляем в конец вызов метода First:
| Код | Point point = points.Where(p => p.X == points.Max(p1 => p1.X)).First();
|
Вот. Теперь компилятор не ругается и получает необходимый результат. Казалось бы, вот оно, счастье Ан нет. Если присмотреться, код-то неоптимальный. На первый взгляд кажется, что выполняется 2n операций: сначала находится максимальный X, а потом элемент с этим значением X. Напомню, что классически эта задача решается за n операций (как выше через foreach). На самом деле этот код ведет себя куда хуже. Дело в том, что points.Max выполняется при каждой итерации (ну действительно, откуда LINQ знать, что это значение является константой?! "Нет, сынок, это фантастика" ). Таким образом, этот скрипт выполняется при помощи n*n операций. Невероятно, но при некоторых n этот вариант может работать даже медленнее бредового варианта с сортировкой (n*n против n*log(n) ). Конечно, пофиксить баг под кодовым названием "расчет point.Max при каждой итерации" не составит труда:
| Код | int maxX = points.Max(p1 => p1.X); Point point = points.Where(p => p.X == maxX).First();
|
Все, что мы сделали, - вынесли вычисление максимального значения X за цикл. Итого, получаем 2*n операций. Лучше, конечно, но все равно попахивает законом дырявых абстракций. Но ведь если проблему нельзя решить "стандартными средствами", никто не запрещает создать свой собственный метод расширения (хвала С# 3.0). Упрощенная версия будет выглядеть примерно так:
| Код | public static Point MaxX(this IEnumerable<Point> source) { if (source == null) throw new ArgumentException("Source is null"); Point result = default(Point); foreach (Point point in source) if ((point != default(Point)) || (point.X > result.X)) result = point; return result; }
|
Используем вот так:
| Код | Point point = points.MaxX();
|
Это заточенный вариант под этот пример. Конечно, лучше создать более унифицированный метод через дженерики, но мне лень 
Добавлено @ 18:24 Забыл добавить, что вариант с методом расширения выполняется за n операций. |