Рассылка закрыта
При закрытии подписчики были переданы в рассылку "BloggLand и Я | Блоггландия" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
№40 рассылки '.Net Собеседник':
Информационный Канал Subscribe.Ru |
.Net Собеседник #40
Содержание- От автора
- Обзор новостей
- Обработка списков с использованием yield и делегатов
- Время кода - Отлавливаем обновление страницы
- Форумы .Net на www.sql.ru
От автора
Здравствуйте, коллеги!
Также снижена цена на подписку журнала в электронном виде (с третьего номера) - теперь он стоит $1/27 руб./5 грн. Как подписаться - подробнее смотрите на сайте.
Обзор новостей
-
Вышел VG.net 2.4: анимированная векторная графика для .NET
- VG.NET – ядро векторной графики для .NET, включающее графический дизайнер, интегрированный в Visual Studio. С версии 2.4 можно создавать текстовые объекты, позиционированные относительно точки, обводить текст, интегрировать свой код отрисовки в класс CustomElement, работать внутри групп в новом режиме Active Group.
-
Вышел Likemedia ClassBuilder -
версия 3.7
- Новая версия известного генератора кода.
-
Передовая технология построения GUI для .NET.
- 9Rays.Net объявила о выходе версии Beta1 нового революционного продукта в области инструментов и графических компонентов для .NET Instrumentation Model Kit. Этот продукт специально разработан для существенного упрощения и оптимизации процесса создания пользовательского интерфейса.
-
Провайдер веб-сервисов Elementool
мигрировал на Microsoft ASP .NET
- Elementool, провайдер веб-инструментов управления проектами, в 10 раз улучшил производительность своих решений после перехода на технологию Microsoft's ASP .NET, подробнее здесь: www.elementool.com.
Статья номера
Обработка списков с использованием yield и делегатов
ЯЗЫК: C#
Автор статьи: Marcus Andrйn
ПЕРЕВОД: Чужа В.Ф. ака hDrummer
КОД К СТАТЬЕ:
ListProcessing_src_new.zip
Вступление
В этой статье описывается, каким образом можно использовать итераторы для обработки списков, реализующих интерфейс IEnumerable. Этот метод не так часто используется в таких языках, как c#, java, так что будет интересно посмотреть, как он работает. Поскольку код использует yield, а также анонимные делегаты, то работать будет только в версии c# 2.0
Простой метод yield (итератор)
class PositiveNumbers : System.Collections.IEnumerable { public System.Collections.IEnumerator GetEnumerator() { int a = 1; while (true) { yield return a; a = a + 1; } } } ... foreach (int num in new PositiveNumbers()) { //Что-то делаем с каждым положительным числом .. } |
Вместо написания класса, реализующего три метода, возвращающих IEnumerator, мы можем в c# 2.0 написать один метод, использующий yield. Доступ к этому методу может быть осуществлён через методы IEnumerator - MoveNext, Reset, Current. (Кстати: yield не поддерживает Reset).
Так как это всё работает? Ответ прост. Сначала вызывается MoveNext, наш метод работает с самого начала. Переменная a устанавливается в 1, мы входим в цикл while и возвращаем a равный 1. В следующий раз, при вызове MoveNext, мы продолжаем со строки после yield, a=a+1, что увеличивает a до 2, мы делаем ещё один шаг в цикле и вызываем yield return. Следующий код продемонстрирует это более чётко.
public System.Collections.IEnumerator GetEnumerator() { yield return "First element"; yield return "Second element"; yield return "Third element"; yield return "Last element"; } |
Этот метод yield (итератор) представляет собой список, всегда содержащий четыре строковых элемента.
Немного синтаксического сахара
Проблема с вышеприведенным подходом заключается в том, что нам нужно по одному классу для каждог итератора. К счастью, в c# 2.0 есть решение для этого. Если yield помещён в метод, возвращающий IEnumerable, то компилятор всё сделает за вас.
class Iterators { public static System.Collections.IEnumerable PositiveNumbers() { int a = 1; while (true) { yield return a; a = a + 1; } } } |
Это значит не только то, что мы можем разместить несколько итераторов в классе. Теперь мы получаем доступ к каждому итератору посредством класса и имени метода, вместо того, чтобы использовать оператор new.
foreach (int num in IteratorsPositiveNumbers()){} |
Наконец, наш итератор возвращает только целые, т.е. мы можем его оптимизировать путём использования шаблонной версии IEnumerable. Небольшое изменение в заголовке метода увеличит скорость его исполнения и уменьшит количество необходимых приведений к типу.
public static System.Collections.Generic.IEnumerable PositiveNumbers() |
Превращаем бесконечный список в конечный
Перечислитель PositiveNumbers, приведенный выше, работает бесконечно. А если нам нужны только некоторые положительные числа? Решение – добавить ещё один итератор. Он будет иметь три аргумента. Индекс первого желаемого элемента, последнего и Ienumerable, содержащий исходный список.
public static System.Collections.IEnumerable SubList(int start, int end, IEnumerable enumerable) { int count = 0; foreach (object o in enumerable) { count++; if (count < start) continue; else if (count <= end) yield return o; else yield break; } } ... //это даёт нам список, содержащий элементы от 5 до 15 IEnumerable numbers = Iterators.SubList(5, 15, Iterators.PositiveNumbers())); |
Наш итератор просто пропускает элементы в списке до тех пор, пока мы не наткнёмся на пятый элемент. Потом мы делаем yield return до появления 16-го элемента. Тут вызывается yield break;. Что равносильно утверждению о том, что в коллекции не осталось элементов.
Отображение
Последний итератор, который мы изучим, получил своё название от функции из языка LISP. Что он делает? Просто берёт метод и список. А потом возвращает список, содержащий элементы, к которым применён взятый метод.
public delegate object MapFunction(object o); /// /// Запускаем эту функцию для каждого элемента списка /// public static IEnumerable Map(MapFunction mapFunction, IEnumerable enumerable) { foreach (object o in enumerable) { yield return mapFunction(o); } } ... foreach (int num in I.Map( // умножаем каждый элемент на 2 delegate(object o){ return ((int)o) * 2; }, I.SubList(5, 15, I.PositiveNumbers()))) { Console.Write("{0} ", num); //Печатает 10 12 14 .. 28 30 } |
Код прост. Мы просто вызываем MapFunction для каждого объекта и возвращаем результат с помощью yield return.
И наконец…
Хотя всё, что приведено в этой статье, можно решить и другим путём, интересно пронаблюдать, как всё это работает со стороны функционального программирования. Особенно интересно посмотреть, как мы обращаемся со списками, содержащими все положительные числа, генерируя элементы по требованию, делая возможным использование бесконечных списков.
Время кода
Отлавливаем обновление страницы
ЯЗЫК: VB.Net
Автор статьи:
Altaf Al-Amin
ПЕРЕВОД: Чужа В.Ф. ака hDrummer
КОД К СТАТЬЕ:
Detecting_Refresh_src.zip ~100 KB
Вступление
Общей проблемой, с которой сталкиваются все веб-разработчики,
является проблема предупреждения обновления выведенной веб-страницы. Проблема
возникает, если предыдущий запрос, отправденный на сервер, был PostBack,
который, например, вставил данные вашей веб-формы в БД. Обновление приводит к
повторной вставке и появлению дублированных записей в БД. Запретить обновлять
страницу пользователю мы не можем. Так что же делать? Можно определить, что
обновление произошло и как-то отреагировать на это.
Стратегия:
Protected Overrides Function SaveViewState() As Object Session("__ISREFRESH") = _refreshState Dim AllStates() As Object = New Object(2) {} AllStates(0) = MyBase.SaveViewState AllStates(1) = Not (_refreshState) Return AllStates End Function |
Как только происходит событие PostBack, вызывается метод LoadViewState.
Protected Overrides Sub LoadViewState(ByVal savedState As Object) Dim AllStates As Object() = savedState MyBase.LoadViewState(AllStates(0)) _refreshState = Boolean.Parse(AllStates(1))<br> _isRefresh = _refreshState = Session("__ISREFRESH") End Sub |
Кстати: переменная _refreshState берётся из ViewState и сравнивается со значением в Session["__ISREFRESH"]. Результат сохраняется в _isRefresh, значение которого доступно через свойство IsRefresh. Ниже приведен весь класс:
Public Class test1 Inherits System.Web.UI.Page #Region " Web Form Designer Generated Code " 'следующее объявление необходимо для Web Form Designer. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() End Sub Protected WithEvents Button1 As System.Web.UI.WebControls.Button Protected WithEvents label1 As System.Web.UI.WebControls.Label 'следующее объявление необходимо для Web Form Designer. 'Не удаляйте и не перемещайте его. Private designerPlaceholderDeclaration As System.Object Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: следующий вызов необходим для Web Form Designer 'Не изменяйте его. InitializeComponent() End Sub #End Region Private _refreshState As Boolean Private _isRefresh As Boolean Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.label1.Text = _isRefresh.ToString End Sub Protected Overrides Sub LoadViewState(ByVal savedState As Object) Dim AllStates As Object() = savedState MyBase.LoadViewState(AllStates(0)) _refreshState = Boolean.Parse(AllStates(1))<br> _isRefresh = _refreshState = Session("__ISREFRESH") End Sub Protected Overrides Function SaveViewState() As Object Session("__ISREFRESH") = _refreshState Dim AllStates() As Object = New Object(2) {} AllStates(0) = MyBase.SaveViewState AllStates(1) = Not (_refreshState) Return AllStates End Function End Class |
При нажатии на элемент, генерирующий отправку страницы на сервер, происходит событие LoadViewState. Эта функция загружает предыдущее состояние ViewState, из которого мы узнаем состояние обновления. Ключевой частью является проверка значения _refreshstate и сверка на идентичность со значением, хранящимся в сессионной переменной, если они равны, значит, пользователь обновлял страницу.
Функция SaveViewState сохраняет текущее значение _refreshState в сессии, так что позже мы можем проверить – обновлял ли пользователь страницу путём нажатия на кнопку «Обновить».
Вывод
В этой статье продемонстрирован упрощённый метод определения события обновления страницы.
Вот и всё.
{К содержанию}
Форумы .Net - вопросы оставшиеся без ответа
Тип
Image в MS SQL и MS Word VBA
Не
могу законектить oracle из MS.NET Web приложения. Помогите пжлст.
отображение
пустой даты
REFERER
header
помогите
потестировать
Как
заставить ASPxDropDownList работать как DropDownList?
Dinamiceskaja
Image v Header Crystal Reporta
CDO.Messge
... тонкость
ABBY
Lingvo Automation
Контрол
через appdomain
На этом сороковый выпуск .Net Собеседника закончен.
До следующего номера.
Чужа Виталий Ф. aka hDrummer, MCAD, MCDBA, MCP
hdrummer@sql.ru - жду ваши предложения и замечания.
http://subscribe.ru/
http://subscribe.ru/feedback/ |
Подписан адрес: Код этой рассылки: comp.soft.prog.dotnetgrains |
Отписаться |
В избранное | ||