Результаты поиска
ITVDN: курсы программирования
Видеокурсы по
программированию
Подписка

300+ курсов по популярным IT-направлениям

Выбери свою IT специальность

Подписка
Подписка

300+ курсов по популярным IT-направлениям

Результаты поиска по запросу: видеокурс c*
Путеводитель ITVDN по C#

Автор: Редакция ITVDN

C# занимает лидирующие позиции во всех рейтингах языков программирования. Так как рынок труда активно развивается, программисты, которые хорошо знают C# и технологии .NET, являются очень востребованными. На ITVDN вы найдете все необходимое, чтобы выучить C# с нуля до профессионального уровня. Курсы записаны сертифицированными разработчикам и тренерами Microsoft. Мы рекомендуем проходить обучение в такой последовательности:    C# Starter, автор Александр Шевчук Выполнение домашних заданий по C# Starter, автор Константин Черный How to C# Starter, автор Богдан Бондарчук Тренажер по C# Starter Visual Studio Tips & Tricks, автор Дмитрий Охрименко  C# Essential, автор Александр Шевчук Выполнение домашних заданий по C# Essential, автор Константин Черный How to C# Essential, автор Богдан Бондарчук Тренажер по C# Essential C# Универсальные шаблоны, автор Николай Мельничук  Unit Тестирование в C#, автор Дмитрий Охрименко  Асинхронное программирование в C# 5, автор Олег Кулыгин C# для профессионалов, автор Александр Шевчук  How to C# Professional, автор Константин Черный Что нового в C# 6.0-7.0, автор Александр Ткаленко Также вас могут заинтересовать записи вебинаров ITVDN: С# - с чего начать и как идти дальше? Работа с Microsoft Word на C# Если вы планируете свое обучение C# с нуля, тогда наилучшим решением будет приобретение подписки ITVDN сроком на 3 или 6 месяцев.
C# против Java: какой язык программирования общего назначения выбрать?

Автор: Yoshitaka Shiotsu

Что такое C#? Что такое Java? C# vs. Java: основные сходства. C# vs. Java: основные различия. Когда стоит использовать C# или Java? C# vs Java – какой из общецелевых, объектно-ориентированных языков программирования лучше всего подойдет вам для работы? Они оба имеют обширные библиотеки, которые можно использовать для создания приложений для ПК, веб, мобильных устройств и других платформ. У обоих есть большие сообщества восторженных поклонников и много онлайн-поддержки. Имея так много общего, выбор правильного языка требует более тонкого, тщательного подхода. Давайте подробнее рассмотрим сходства и различия между C# и Java. Что такое C#?   C# – это язык программирования общего назначения, который впервые появился в 2000 году в рамках инициативы Microsoft .NET. Он был разработан для общей языковой инфраструктуры (CLI) – открытой спецификации, разработанной Microsoft и стандартизированной ISO и ECMA. Приложения C# скомпилированы в байт-код, который может запускаться при реализации CLI.   Что такое JAVA?   Java, первоначально выпущенный Sun Microsystems в 1995 году, является языком программирования общего назначения, который был разработан с конкретной целью, позволяющей разработчикам “write once, run anywhere”, то есть написать код единожды и запускать в любом месте. Java-приложения скомпилированы в байт-код, который может запускаться при реализации виртуальной машины Java (JVM). Подобно CLI, JVM помогает преодолеть разрыв между исходным кодом и 1 и 0, которые понимает компьютер. C# VS. JAVA: ОСНОВНЫЕ СХОДСТВА  Появление как Java, так и C#, тесно связано с переходом от низкоуровневых языков программирования, таких как языки программирования C++, к языкам более высокого уровня, которые компилируются в байт-код. Байт-код можно запустить на виртуальной машине. С этим связан ряд преимуществ, в первую очередь, возможность написания кода, который будет понятен человеку и будет работать на любой аппаратной архитектуре, на которой установлена виртуальная машина. Если отбросить синтаксические причуды в сторону, то неудивительно, что эти два подобные между собой языка так популярны для разработчиков приложений. Вот несколько основных сходств между C# и Java: Безопасность типов. Ошибка типа возникает, когда тип данных одного объекта ошибочно назначается другому объекту, создавая непреднамеренные побочные эффекты. И C#, и Java работают на то, чтобы гарантировать выявление таких типов незаконных приведений во время компиляции. Если приведение не может быть применено к новому типу, тогда во время выполнения такие исключения будут удалены. Сборка мусора: На языках более низкого уровня управление памятью может быть утомительным, ведь нужно помнить о том, что необходимо правильно удалить новые объекты, чтобы освободить ресурсы. На С# и Java есть встроенная сборка мусора, которая помогает предотвратить утечку памяти путем удаления объектов, которые больше не используются приложением. Утечки памяти все еще могут возникать, но благодаря основам управления памятью -  это уже не ваша проблема. Одиночное наследование. Оба языка поддерживают одиночное наследование – это означает, что существует только один путь из любого базового класса в любой из его производных классов. Это ограничивает непреднамеренные побочные эффекты, которые могут возникать при наличии нескольких путей между несколькими базовыми классами и производными классами. Diamond pattern – книжный пример этой проблемы. Интерфейсы. Интерфейс представляет собой абстрактный класс, где все методы абстрактны. Абстрактным методом является тот метод, который объявлен, но не содержит подробностей его реализации. Код, определяющий любые методы или свойства, определенные интерфейсом, должен предоставляться классом, который его реализует. Это помогает избежать двусмысленности паттерна diamond, поскольку всегда ясно, какой базовый класс реализует данный производный класс во время выполнения. Результатом является чистая иерархия линейных классов одиночного наследования в сочетании с некоторой универсальностью множественного наследования. Фактически использование абстрактных классов является одним из способов множественного наследования языков, которые могут преодолеть проблему паттерна diamond. C# VS. JAVA: ОСНОВНЫЕ РАЗЛИЧИЯ Важно помнить, что C# берет свое начало в желании Microsoft иметь собственный «Java-подобный» язык для платформы .NET. Поскольку C# не создавался в вакууме, новые функции были добавлены и настроены для решения проблем, с которыми сталкивались разработчики Microsoft, когда они изначально пытались создать свою платформу на Visual J++. В то же время сообщество Java с открытым исходным кодом продолжало расти и между этими двумя языками развивалась гонка технических вооружений. Вот некоторые из основных различий между C# и Java. Windows vs open-source. Хотя существуют реализации с открытым исходным кодом, C# в основном используется в разработке для платформ Microsoft – .NET Framework CLR и является наиболее широко используемой реализацией CLI. На другом конце спектра Java имеет огромную экосистему с открытым исходным кодом и у него открылось второе дыхание отчасти благодаря тому, что Google использует JVM для Android. Поддержка обобщений (Generics): Generics улучшает проверку типов с помощью компилятора, в основном удаляя приведения из исходного кода. В Java средства обобщений реализуются с использованием стираний. Параметры общего типа «стираются», а при компиляции в байт-код добавляются приведения. C# также использует обобщения, интегрируя его в CLI и предоставляя информацию о типе во время выполнения, что дает небольшое увеличение производительности. Поддержка делегатов (указателей): В C# есть делегаты, которые по существу служат в качестве методов, которые могут быть вызваны без знания целевого объекта. Для достижения такой же функциональности в Java вам необходимо использовать интерфейс с одним методом или другим способом обхода, который может потребовать нетривиального количества дополнительного кода, в зависимости от приложения. Проверяемые исключения: Java различает два типа исключений – проверяемые и непроверяемые. C# выбрал более минималистский подход, имея только один тип исключения. Хотя способность ловить исключения может быть полезна, она также может отрицательно влиять на масштабируемость и контроль версий. Полиморфизм: C# и Java используют очень разные подходы к полиморфизму. Java допускает полиморфизм по умолчанию, C# же должен вызывать ключевое слово «virtual» в базовом классе и ключевое слово «override» в производном классе. Перечисления (Enums): в C# перечисления представляют собой простые списки именованных констант, где базовый тип должен быть целым. Java представляет перечисления более глубоко, рассматривая его как именованный экземпляр типа, что упрощает добавление пользовательского поведения к отдельным перечислениям. Когда стоит использовать C# или Java? Язык, который вы в конечном итоге решите использовать, будет во многом зависеть от платформы, которую вы выбрали для своего проекта. Сегодня C# используется в основном для реализации CLI на .NET Framework, Mono и Portable.NET. Если ваше программное обеспечение или веб-приложение создаются для Windows, C# будет работать лучше всего с набором технологий .NET. Тем не менее, если вы хотите разрабатывать для Unix, Linux или других платформ за пределами платформы Microsoft, экосистема с открытым исходным кодом – Java – лучший выбор. Сообщество постоянно создает новые библиотеки и инструменты. Появились новые мощные языки, такие как Scala, Clojure и Groovy, и они все тоже основаны на JVM. К тому же это неплохо, что большинство реализаций JVM являются общедоступными и бесплатными. Java – основной язык разработки, который использует Google для Android – самой большой мобильной операционной системы в мире в настоящее время. Имейте в виду, что перечисленные выше преимущества незначительны, и ни один из языков не исчезнет в ближайшее время. Оба языка существуют достаточно долго и, на самом деле, вы не сможете ничего такого построить на одном языке, чего бы  не смогли построить на другом. Итог: выберите язык, который лучше всего подходит для платформы вашего проекта. Источник: https://www.upwork.com/hiring/development/c-vs-java/
Введение в ASP.NET Core

Автор: Daniel Roth

ASP.NET Core представляет собой существенный редизайн ASP.NET. В этом разделе представлены новые концепции в ASP.NET Core, а также содержатся объяснения, как они помогают разрабатывать современные веб-приложения.   Что такое ASP.NET Core? ASP.NET Core – это новый общедоступный и кроссплатформенный фреймворк для создания современного облака приложений, связанных с подключением к интернету, таких как веб-приложения, приложения для интернета вещей и мобильных серверов. Приложения ASP.NET Core могут работать на .NET Core или на полной платформе .NET Framework. Этот фреймворк был спроектирован таким образом, чтобы обеспечить оптимизированную платформу разработки для приложений, которые перемещаются в облако или выполняются локально. Он состоит из модульных компонентов с минимальной перегрузкой, поэтому вы сохраняете гибкость при построении своих решений. Существует возможность разрабатывать и запускать кроссплатформенные ASP.NET Core приложения на Windows, Mac и Linux. Фреймворк ASP.NET Core общедоступен на GitHub. Зачем строить ASP.NET Core? Первая предварительная версия ASP.NET появилась почти 15 лет назад как часть платформы .NET Framework. С тех пор миллионы разработчиков использовали технологию для создания и запуска отличных веб-приложений. За эти годы удалось добавить и разработать множество возможностей. ASP.NET Core имеет ряд архитектурных изменений, которые приводят к более компактной и модульной структуре. ASP.NET Core больше не основывается на файле System.Web.dll. Он основан на наборе детальных и хорошо структурированных пакетов NuGet. Это позволяет оптимизировать приложение с помощью пакетов NuGet, которые вам необходимы. Преимущества меньшей площади поверхности приложения включают: более строгую защиту, сниженный уровень обслуживания, улучшенную производительность и снижение затрат в модели «плати за то, что используешь». С помощью ASP.NET Core вы достигните таких основных улучшений: Единая история создания для Web UI и Web APIs Интеграция современных клиентских фреймворков и схем разработки Конфигурация, готовая для работы в облаке и основывающаяся на окружении Встроенная поддержка внедрения зависимостей Новый легкий и модульный HTTP-запрос Возможность хостироваться в IIS либо в вашем собственном приложении Фреймворк построен на платформе .NET Core, которая поддерживает истинное совместное управление версиями приложений Поставка как полные NuGet пакеты Новый инструментарий, который упрощает разработку современных веб-приложений Сборка и работа кроссплатформенных ASP.NET приложений на Windows, Linux и Mac Общедоступный и социально-ориентированный фремворк   Создание web UI и web APIs с использованием ASP.NET Core MVC Вы можете создавать службы HTTP, которые охватывают широкий круг клиентов, включая браузеры и мобильные устройства. Поддержка нескольких форматов данных и согласования содержимого – уже встроены. ASP.NET Core - идеальная платформа для создания web APIs и RESTful приложений на .NET Core. Вы можете создавать хорошо факторизованные и тестируемые веб-приложения, которые следуют шаблону Модель-Вид-Контроллер (MVC). Razor обеспечивает продуктивный язык для создания Views Тег-хэлперы позволяют серверному коду участвовать в создании и рендеринге HTML- элементов в файлах Razor Привязка модели автоматически отображает данные из HTTP-запросов в параметры метода действия Проверка модели автоматически выполняет проверку на стороне клиента и на стороне сервера   Разработка клиентской стороны ASP.NET Core предназначен для беспроблемной интеграции с различными клиентскими платформами, включая AngularJS, KnockoutJS и Bootstrap. Материал подготовлен на основе статьи: https://docs.microsoft.com/en-us/aspnet/core/. Авторы: Daniel Roth, Rick Anderson, Shaun Luttin
Построение микросервисов на ASP.NET Core (без MVC)

Автор: Filip W

Существует несколько причин для создания суперпростых и легких HTTP сервисов, которые еще называются «микросервисами». Нет нужды говорить обо всех операционных и архитектурных преимуществах такого подхода к построению системы, так как это не раз обсуждалось на разных ресурсах. Я хотел бы показать пару техник построения весьма простых и компактных HTTP сервисов на основе ASP.NET Core без использования каких-либо фреймворков и с минимальным разрастанием кода. Предпосылки То, что я буду обсуждать в данной статье, базируется на пакете ASP.NET Core 1.2, который на момент написания еще не был в релизе. Я использую CI, поданную в ASP.NET Core, поэтому мой Nuget.config выглядит таким образом: Когда версия 1.2 добавится в Nuget, этого больше не потребуется. ASP.NET HTTP endpoints без MVC ASP.NET Core позволяет определить HTTP endpoints непосредственно на спецификации OWIN, которая построена вокруг, не используя полномасштабную структуру MVC и ее контроллеры для обработки входящих запросов. Так было с самого начала – вы могли использовать компоненты промежуточного программного обеспечения для обработки входящих HTTP запросов и короткую схему ответа непосредственно клиенту. Во многих проектах на основе профиля ASP.NET Core уже используется такая техника, например, Identity Server 4.  Это не новая концепция – нечто подобное существовало (хотя и в ограниченной форме) в классическом ASP.NET с HTTP модулями и HTTP обработчиками. Позднее, в Web API можно было определить обработчики сообщений для обработки HTTP запросов без необходимости определения контроллеров. И, наконец, в OWIN и в Project Katana это также было возможно через подключение к пользовательским компонентам промежуточного ПО. Другой альтернативой является точное определение пользовательского IRouter и прикрепление от него различных endpoints. Основное различие между этим подходом и подключением пользовательских компонентов промежуточного ПО в том, что маршрутизация сама по себе представляет единое промежуточное ПО. Это также дает нам возможность для гораздо более сложного сопоставления URL шаблона и определения ограничения маршрута – то, что Вам нужно было бы обрабатывать вручную в случае промежуточного программного обеспечения. ASP.NET Core 1.2 скоро представит ряд новых методов расширения на IRouter, которые сделают создание простых и компактных HTTP endpoints еще проще. Станет возможным заполнить более ранние версии ASP.NET Core этой функциональностью путем простого копирования новых расширений в ваш проект. Настройка базы для простого и компактного HTTP API Это project.json для нашего микросервиса. Он содержит только самые базовые пакеты. Мы используем здесь абсолютный минимум: • Kestrel и IIS интеграция выступают в качестве хоста сервера • пакет маршрутизации • пакеты протоколирования и конфигурации Для того, чтобы привести и наш код к абсолютному минимуму, мы можем даже бросить концепцию Startup класса для нашей API установки, и просто писать весь код бэкэнда API в одном файле. Вместо того, чтобы закреплять все в типичные Startup точки расширения, такие как методы Configure() и ConfigureServices(), мы повесим все на WebHostBuilder. WebHostBuilder довольно часто игнорируется разработчиками ASP.NET Core, потому что генерируется шаблоном в качестве точки входа внутри класса Program, и, как правило, нам не нужно даже изменять его – поскольку он по умолчанию указывает на класс Startup, где происходит почти вся работа по настройке и конфигурации. Тем не менее, он также предоставляет аналогичные зацепки, которые есть у Startup, поэтому можно просто определить все непосредственно на WebHostBuilder. Наша базовая API конфигурация приведена ниже. Она еще ничего не делает с точки зрения воздействия HTTP endpoints, но она полностью функциональна со стороны процесса подготовки создания (маршрутизатор подключен), входа в консоль и захвата конфигурации из JSON и переменных окружения. Мне нравится этот подход, поскольку он поразительно краток. Примерно в 20 строках кода мы имеем отличную базу для легкого HTTP API. Естественно, мы могли бы обогатить ее более широкими возможностями по необходимости – например, добавить в наши собственные сервисы или добавить проверку маркера с использованием соответствующих пакетов интеграции из Microsoft.Security или IdetntityServer4. Добавление HTTP endpoints в наше решение Финальный шаг – это добавление HTTP endpoints. Мы сделаем это, используя вышеупомянутый расширяющий метод, который будет представлен в ASP.NET Core 1.2. Для демонстрации нам необходима любая модель и сымитированные данные, чтобы использовать стандартный Contact и примеры ContactRepository. Код ниже запускается в расширяющем методе Configure() на WebHostBuilder, о чем уже было упомянуто ранее. Он показывает HTTP обработчики для получения всех контактов и получения контакта по ID. Этот код должен быть достаточно самостоятельным в описании – мы делегируем справочную операцию в хранилище и затем просто выводим результат в HTTP ответе. Расширяющий метод-маршрутизатор также дает нам доступ к значениям данных маршрута, делая простым управление сложных URI. К тому же, мы можем использовать обычные шаблоны маршрутов ASP.NET Core со всей мощью ограничений, которые очень удобны, например, так как вы и ожидаете, contacts/{id:int} не будут поставлены в соответствие для нецелочисленных ID. Я также помог себе, добавив удобный расширяющий метод для написания ответного потока. Финальный шаг – это добавление в HTTP endpoints изменения состояния серверной части: POST (добавить) новый контакт PUT контакт (изменить существующий) DELETE (удалить) контакт Нам потребуется дополнительный расширяющий метод, чтобы упростить это, потому что необходимо дессерилизовать запрос тела потока в JSON и нам хотелось бы проверить аннотацию данных нашей модели, чтобы гарантировать, что запрос от клиента является валидным. Очевидно, что будет глупо повторять код раз за разом. Этот расширяющий метод приведен ниже и в нем используются JSON.NET и System.ComponentModel.DataAnnotations.Validator. Заметьте, что метод вернет клиенту ‘400 Bad Request’, если модель не окажется валидной. Например, требуемое поле будет пропущено – мы также получим ошибку валидации. Далее показано определение HTTP endpoints: Вот и все – вы можете улучшить этот код, добавив в него, например, удобные методы чтения и выбора значений из RouteDataDictionary. Также не вызовет проблем усиление кода аутентификацией и даже внедрение в него новой авторизационной политики ASP.NET Core. Полный код нашего «микросервиса» (без вспомогательных расширяющих методов, которые, я предполагаю, вы в любом случае захотите собрать воедино и заново использовать) показан ниже – и мне нравится полученный результат. Я считаю, что это весьма привлекательный, лаконичный способ построения простого и компактного API в ASP.NET Core. Исходники доступны на Github. Оригинал статьи тут: http://www.strathweb.com/2017/01/building-microservices-with-asp-net-core-without-mvc/
Использование ASP.NET Core JS сервисов совместно с Client-side фреймворками

Автор: Rion Williams

Наверное, сейчас самое подходящее время для разработки веб-приложений, конечно, если вам подходит эта среда. Такие фрэймворки, как Angular, Aurelia, React и многие другие – отличные инструменты, но их изучение нелегко даётся  и нужно помучиться, чтобы ими овладеть. Node-модули, npm, gulp, grunt, bower, webpack, babel и так далее. Зависимости, конфигурации ОС и все остальные виды мусора часто встают на пути. Ужасно, когда уходят часы, чтобы разобраться в этом «болоте». Довольно часто вам хочется просто работать по схеме «Файл – Новый проект», и чтобы другие разбирались с остальной чепухой. Что ж, ребята из Microsoft согласны и готовы помочь. Встречайте JavaScriptServices. JavaScriptServices – набор технологий для разработчиков ASP.NET Core, обеспечивающий инфраструктуру, которую вам необходимо выстроить в приложении со стороны клиента, используя Angular, Aurelia, React и другие фреймворки. Это полностью open-source проект, и он содержит кучу фич, на которые вы и не надеялись, а именно: Набор NuGet/NPM пакетов, которые предлагают такой функционал:       Вызов произвольного NPM-пакета в рантайме из .NET code       Серверная предварительная визуализация SPA-компонентов       Межплатформенное программное обеспечение Webpack       Hot module replacement, возможность очень быстро отобразить изменения в браузере без перезагрузки страницы       Серверная и клиентская маршрутизация и валидация интеграции       "Cache priming" (для Angular 2)       "Lazy loading" (для Knockout) Хотите использовать Webpack, чтобы все это создать? Без проблем. Хотите запустить свой JavaScript код на сервере в рантайме? JavaScriptServices сделает и это. JavaScriptServices создан для того, чтобы устранить всё, что мешает, и позволить вам писать собственные приложения со всеми фичами, которыми только пожелаете. Как бонус на GitHub есть отчет по JavaScriptServices с примерами и гайды для начинающих. Создание Brand New Application. Начать очень просто. Проект идет с заранее настроенным генератором Yeoman, что позволяет раскрутить новый проект из командной строки в считанные секунды. Во-первых, установите необходимые шаблоны проекта из npm:     Затем просто создайте свой проект:     Дальше вы увидите забавную подсказку ASCII, дабы знать, как сконфигурировать проект:     После выбора команды ‘dotnet run’ вы должны получить то, что ожидали.  Уже сделали приложение? Если у вас уже есть существующее ASP.NET приложение и вы хотите покопаться в создании нового front-end для него, используя один из вышеупомянутых фрэймворков, JavaScriptServices поможет в этом. Есть три пакета NuGet, которые можно использовать в проекте в зависимости от ваших потребностей: Microsoft.AspNetCore.NodeServices – если Вы работаете с Node.js, тогда это то, что нужно. В сущности, он дает возможность .NET code выполнить JavaScript на сервере в среде Node.js (то есть использует NPM-пакеты во время выполнения вашего .NET Core  приложения). Microsoft.AspNetCore.SpaServices – для создания SPA-приложений на Angular 2 или React. Пакет предоставляется со всеми необходимыми инструментами для управления серверным pre-рендером, а также межплатформенной поддержкрй для webpack. Microsoft.AspNetCore.AngularServices – очень похожий на SPAServices пакет, за исключением того, что он имеет свойственные Angular вспомогательные методы и поддерживает “cache priming”, который предварительно оценивает AJAX запросы на сервере, так что вашему client-side коду не нужно будет подключаться к сети после загрузки. Подключите все нужные пакеты к вашему NET.Core приложению, и оно будет работать с удобными для вас client-side фреймворками (и с любыми другими межплатформенными фичами, например, серверной обработкой).  Может ли обычный пользователь создать такой же проект? Для некоторых пользователей (обычных юзеров) мигающий курсор чёрной командной строки подобен ночному кошмару. Если вы как раз из таких, не беспокойтесь, для вас тоже кое-что есть. Недавно команда Visual Studio Web Tools выпустила ASP.NET Core Template Pack extension. Он опирается на сервисы JavaScript для скаффолдинга нового ASP.NET Core проекта, используя ваш любимый фрэймворк:     Работа над JavaScriptServices еще в процессе и пока добавлены не все популярные фрэймворки. Однако, Core Template Pack – это open-source проект, так что если вам необходимо поработать с фрэймворком MagicJSFoo, вы действительно сможете это сделать. Оригинал: http://rion.io/, 05 December 2016.
Расчет сложных процентов за период времени в C#

Автор: Редакция ITVDN

Введение Данный пример показывает, как рассчитать сложный процент через временной период. Введите основную сумму, процентную ставку и количество лет в TextBox. Когда Вы кликните Рассчитать, программа использует следующий код для отображения баланса в течение следующих лет.  // Расчет и отображение процентов для следующих лет private void btnCalculate_Click(object sender, EventArgs e) {     lstResults.Items.Clear();     double principle = double.Parse(txtPrinciple.Text);     double interestRate = double.Parse(txtInterestRate.Text);     int numYears = int.Parse(txtNumYears.Text);     for (int i = 1; i <= numYears; i++)     {         double balance = principle * Math.Pow(1 + interestRate, i);         lstResults.Items.Add("Year " + i.ToString() + "\t" +             balance.ToString("C"));     } } Программа просто перебирает годы, рассчитывая сложный процент по формуле:    balance = principle * Math.Pow(1 + interestRate, i) Это простая формула сложного процента, поэтому расчет делается лишь раз в год. Интересно знать: чтобы посчитать, сколько нужно времени чтобы удвоить Ваши деньги, можно использовать «Правило 72-х». Разделите процентную ставку на 72 и результат покажет приблизительное количество лет, которые потребуются для удвоения суммы Ваших денег. Для примера, при ставке 7.2%  это займет около 10 лет. Это довольно приблизительная оценка.
Использование HTML Agility Pack и CSS Selectors

Автор: Редакция ITVDN

Введение В следующих примерах используется HTML Agility Pack (НАР), чтобы загрузить HTML в объект модели документа (DOM) и разбить на узлы. Дополнительно есть случаи, когда приходилось анализировать документ об элементах, которые не являются действительно узлами, такие как комментарии. В дополнение к наблюдениям около HAP в целом будут указаны методы расширения, предоставляемые пакетом HAP.CSSSelectors, что позволяет значительно проще выбирать. Задний план Был успешно использован Html Agility Pack для клиента, проанализированы HTML документы, чтобы извлечь необходимую информацию. Расширения CSSSelector будет добавлять новый мощный уровень абстракции, чтобы собрать необходимые данные. Использование кода Пакеты для примера нужно будет импортировать с помощью NuGet. Описания пакетов будут загружены в проекте, но нужно будет установить менеджер пакетов NuGet для восстановления библиотек. В проект был включен очень простой HTML файл с примерами вопросов, которые необходимы для решения своих проектов. Чтобы проверить без лишних изменений, необходимо скопировать файл HTML в следующем дисководе и каталоге - C: \ TestData. HtmlAgility имеет ряд классов, доступных для его добавляемых классов и перечисления, которые представляют различные части DOM, эти классы включают HtmlAttribute, HtmlAttributeCollection, HtmlCommentNode и так далее. Первый класс, который мы будем изучать, это HTMLDocument класс. Этот класс имеет методы для загрузки и анализа документа в его соответствующих частях. В исходном коде вызывается каждая секция кода, использующая номенклатуру (часть X), где X представляет собой число. Чтобы использовать, следующая строка должна быть реализована: HtmlAgilityPack.agpack = new HtmlAgilityPack.HtmlDocument(); Следующий метод вызывает метод для загрузки документа. Вы можете загрузить его из строки:   agpack.LoadHtml(Html string) //or from a resource – agpack.Load(@"c:\testdata\testdat.htm");   Файл в себя включает недостающий закрывающийся тег шрифта и неуместный закрывающий тег. Он прекрасно работает в браузере, не выдает ошибку в HAP, но может быть проверенным на это. var errors = agpack.ParseErrors; ParseErrors будет возвращать коллекцию и подсчет ошибок. Достаточно интересная вкладка, закрытие шрифта не выдаст ошибку. После того, как документ был загружен, двумя основными способами для поиска являются:  SelectNodes(string XPath)  // from the DocumentNode GetElementbyId(string Id) // from the HtmlDocument Поскольку может быть только один ID, getElementById вернет один узел и SelectNodes вернет коллекцию узлов, потому что с помощью XPath он может соответствовать одному или нескольким элементам. Находим приложение, где будет добавляться несколько файлов вместе, ограничивающее каждый документ с начальным и конечным комментариями. Ниже показано, как обрабатывать разделения этого документа обратно в его составную часть. Файл, который включен, имеет секцию, которая очерчена с комментариями:  HTML Body  Вы можете использовать следующую команду, чтобы получить комментарий: var comment = agpack.DocumentNode.SelectNodes("//comment()[contains(., 'Start Table:')]"); Это говорит от всего документа ("//") выбор комментариев, что содержат от текущего местоположения (.) слово Начало табл. Так как это является комментарием, то не имеет дочерних узлов и внутреннего текста, только текст самого комментария. Это полезно, если то, что вы хотите сделать - это разобрать комментарий, чтобы определить значение в комментарии (номер счета в данном случае), но на самом деле не поможет, если вы хотите видеть текст между комментариями. Чтобы достичь этого, возвращаемся обратно в регулярные выражения и группировки. var html = Regex.Match(agpack.DocumentNode.InnerHtml,@"(?.*)",RegexOptions.Singleline).Groups[1];   Теперь в html.Value имеется текст между двумя тегами. Переходим к нахождению элементов в DOM, первый пример находит узел, используя getElementById. Есть три таблицы, но только два идентификатора возложены на них. Одним из них является ID = "abc", другой ID = "table3". Начнем с таблицы  ID = "abc": var node = agpack.GetElementbyId("abc"); Это вернет один узел, представляющий таблицу. InnerHtml будет содержать весь текст между тегами.  Он также будет содержать набор узлов, представляющих DOM структуру таблицы. Один из подходов к получению узла строк заключается в использовании Linq, чтобы обнаружить их: var rownodes = node.ChildNodes.Where(w => w.OriginalName == "tr"); Если проверить подсчет, вы увидите, что у вас есть три строки. Однако, на самом деле существует четыре ряда, первый записанный  не будет найден. Другой подход заключается в использовании SelectNodes на узле, чтобы обнаружить элементы tr. rownodes = node.SelectNodes("tr"); Но это также проблема - найти все строки, проще найти элементы управления. Как насчет node.SelectNodes ("/ tr")? Это ничего не возвращает. Как насчет node.SelectNodes ("// tr")? Хорошая новость состоит в том, что он нашел недостающую строку вместе со всеми строками (12) в документе. После небольшого углубления нашлись следующие два рабочих решения: rownodes = node.SelectNodes(node.XPath + "//tr"); //or // http://www.w3schools.com/xsl/xpath_axes.as rownodes = node.SelectNodes("descendant::tr"); это возвращает все четыре. Возможно, HAP делал бы SelectNodes от текущего узла "//tr" и работал бы, увы "//" - говорит искать от корня документа. Но второй вариант работает, как потолок от выбранного узла. Аналогичным образом мы можем найти все td элементы, используя те же процедуры. Отметим, что для таблицы нужно 3 вернуть двенадцать td элементов, даже если они являются дочерними. node = null; node = agpack.GetElementbyId("table3") nodes = node.SelectNodes("descendant::td"); Переходим к HAP.CssSelectors. Это находится на вершине HtmlAgility пакета и будет на самом деле обеспечивать установку в качестве части пакета NuGet. Это позволяет выбрать элементы, используя CssSelectors, нежели XPath. Например:  rownodes = agpack.QuerySelectorAll("#abc tr");   В этом случае не нужно искать в узле, просто, выбрав из всего документа, он вернет ожидаемых 4 ряда. listTDNodes = agpack.QuerySelectorAll("#table3 td"); Ниже приведен пример получения только s (три) во втором ряду.   listTDNodes = agpack.QuerySelectorAll("#table3 tr:nth-child(2) td"); Это вернуло двенадцать пунктов, четыре ряда из 3 колоноки. Одно замечание. Способ QuerySelectorAll возвращается, как список <узлов>, а не коллекция узлов. Это важно знать, если планировать смешивать и сочетать. В дополнение к выбору по идентификатору (#) можно выбрать по классам (.), это гораздо проще, чем искать атрибут с классом, используя XPath. listTDNodes = agpack.QuerySelectorAll(".table"); Возвращаем первую и третью таблицу с классом table. Точки интереса В заключении скажем, что продление CssSelectors - это еще один полезный инструмент для легкого выбора элементов, без необходимости копать вглубь XPath или перебирать коллекции. Источник: http://www.codeproject.com/Articles/1038320/Using-HtmlAgility-pack-and-CssSelectors
Использование LINQ на объектах в языке C#

Автор: Редакция ITVDN

Введение Применение LINQ к объектам подразумевает, что можно использовать LINQ для запроса объекта из коллекции. Возможно использование LINQ для получения доступа к структурам данных, хранящихся в оперативной памяти (в структурах данных in-memory). Возможно запросить любой тип объекта, который реализует интерфейс IEnumerable или IEnumerable, относящийся к общему типу. Списки, массивы, словари – некоторые коллекции объектов, запрашиваемые с помощью LINQ. В этой статье будет показано, как выполняется запрос различных объектов с использованием операторов LINQ и избегается необходимость использования метода зацикливания для фильтрации данных. Не используя LINQ, необходимо проходить через значения снова и снова, а затем находить необходимые детали. Однако, с помощью LINQ можно запросить непосредственно сами коллекции данных и отфильтровать искомые значения, не используя зацикливание. LINQ предоставляет мощные возможности по фильтрации, группировке и упорядочиванию, не требующие больших объемов исходного кода. Например, если необходимо выяснить типы, хранящиеся в сборке, затем отфильтровать необходимые данные, можно использовать LINQ для запроса деталей сборки, используя классы System.Reflection. Пространство имен System.Reflection содержит типы, извлекающие информацию о сборках, модулях, членах, параметрах и других объектах как о коллекциях управляемого кода, исследуя их метаданные. Кроме того, файлы в папке представляют собой набор объектов и эти объекты можно запросить, используя LINQ. Далее будут представлены некоторые примеры запросов. Массив целых чисел Следующий пример демонстрирует целочислительный массив, содержащий некоторый набор целых чисел. Можно применить запросы LINQ в массиве для извлечения требуемых значений. int[] integers = { 1, 6, 2, 27, 10, 33, 12, 8, 14, 5 };        IEnumerable twoDigits =        from numbers in integers        where numbers >= 10        select numbers;        Console.WriteLine("Integers > 10:");        foreach (var number in twoDigits)        {           Console.WriteLine(number);        } Переменная integers содержит массив целых чисел с разными значениями. Переменная twoDigits, имеющая тип IEnumerable, проводит запрос. Для получения результата необходимо выполнение запроса. Исполнение запроса произойдет, когда переменная запроса будет итерироваться в цикле вызовом GetEnumerator() для перечисления результата. Любая переменная типа IEnumerable может быть перечислена с использованием цикла foreach. Типы, поддерживающие IEnumerable или производный интерфейс, например, IQueryable, называют запрососпособными типами. Присутствуют также некоторые нетипичные коллекции данных, например, ArrayList, которые также могут быть запрошены с помощью LINQ. Для этого необходимо явно объявить тип ранжированной переменной для конкретного типа объекта в коллекции, как в примерах ниже. Переменная twoDigits проведет запрос для извлечения значений, которые не меньше 10. Таким образом одно за другим извлекаются числа из массива. Цикл будет выполнять запрос, а затем будет выводить в консоль значения, полученные из массива. Как можно заметить, выше продемонстрирован достаточно простой способ получения необходимых данных из коллекции. Если нужны только первые четыре значения коллекции, можно использовать метод запроса Take() на необходимой коллекции. Ниже написано, как можно извлечь первые четыре элемента коллекции и вывести их в консоль, используя цикл. IEnumerable firstFourNumbers = integers.Take(4);    Console.WriteLine("First 4 numbers:");    foreach (var num in firstFourNumbers)    {       Console.WriteLine(num);    } Противоположность метода Take() – оператор Skip(), который используется для пропуска определенного количества первых элементов и получения остальных. В примере ниже будет пропущено первые 4 элемента.  ​IEnumerable skipFirstFourNumbers = integers.Skip(4);    Console.WriteLine("Skip first 4 numbers:");    foreach (var num in skipFirstFourNumbers)    {       Console.WriteLine(num);    } В примерах выше было продемонстрированно, как извлечь/пропустить определенное количество начальных элементов списка. Если необходимо извлечь/пропустить заранее неизвестное число элементов, используются методы TakeWhile() и SkipWhile(), которые работают, пока не будет найдено совпадение. В коде ниже будет изображено, каким образом получить все номера из коллекции, которые стоят до значения 50. TakeWhile() использует выражение для включения элементов коллекции, пока условие истинно, и игнорирует другие элементы списка. Выражение представляет собой условие, проверяющее элементы коллекции на совпадение. int[] integers = { 1, 9, 5, 3, 7, 2, 11, 23, 50, 41, 6, 8 };    IEnmerable takeWhileNumber = integers.TakeWhile(num =>       num.CompareTo(50) != 0);    Console.WriteLine("Take while number equals 50");    foreach (int num in takeWhileNumber)       {          Console.WriteLine(num.ToString());       } Подобным образом работает и метод SkipWhile(), только он пропускает значения, а не извлекает их. Самая высокая эффективность использования данных методов наблюдается при их использовании на упорядоченных списках, т.к. их выполнение прекращается при первом невыполнении условия поиска. IEnumerable skipWhileNumber = integers.SkipWhile(num =>       num.CompareTo(50) != 0);    Console.WriteLine("Skip while number equals 50");    foreach (int num in skipWhileNumber)    {       Console.WriteLine(num.ToString());    } Коллекции объектов В этом разделе будет показано, каким образом можно запросить произвольную коллекцию объектов. Будет использован объект Icecream, построена коллекция, после чего ее можно будет запросить. Класс Icecream в следующем коде содержит различные свойства (имя, ингредиенты, вес, холестерин и т.д.) public class Icecream     {         public string Name { get; set; }         public string Ingredients { get; set; }         public string TotalFat { get; set; }         public string Cholesterol { get; set; }         public string TotalCarbohydrates { get; set; }         public string Protein { get; set; }         public double Price { get; set; }     } Далее строится список Icecreams, используя ранее определенный класс. List icecreamsList = new List         {             new Icecream {Name="Chocolate Fudge Icecream", Ingredients="cream,                 milk, mono and diglycerides...", Cholesterol="50mg",                 Protein="4g", TotalCarbohydrates="35g", TotalFat="20g",                 Price=10.5         },         new Icecream {Name="Vanilla Icecream", Ingredients="vanilla extract,             guar gum, cream...", Cholesterol="65mg", Protein="4g",             TotalCarbohydrates="26g", TotalFat="16g", Price=9.80 },             new Icecream {Name="Banana Split Icecream", Ingredients="Banana, guar             gum, cream...", Cholesterol="58mg", Protein="6g",             TotalCarbohydrates="24g", TotalFat="13g", Price=7.5 }         }; Имеется коллекция icecreamsList, состоящая из трех объектов со значениями типа Icecream. Пусть теперь необходимо извлечь всё мороженное, стоящее меньше 10. Можно использовать зацикливание, при котором необходимо смотреть на цену каждого элемента списка друг за другом, затем извлечь объекты, которые имеют меньшие значения поля Price. Использование LINQ позволяет избежать итерирования всех объектов и их свойств для поиска необходимых, т.е. облегчает поиск. Далее будет представлен запрос, выбирающий мороженое с низкими ценами из коллекции. Для работы запрос использует оператор where. Внешне запрос напоминает запрос из реляционной БД. Запрос выполняется, когда переменная типа IEnumerable перечислена в цикле. List Icecreams = CreateIcecreamsList();     IEnumerable IcecreamsWithLessPrice =     from ice in Icecreams     where ice.Price < 10     select ice;     Console.WriteLine("Ice Creams with price less than 10:");     foreach (Icecream ice in IcecreamsWithLessPrice)     {         Console.WriteLine("{0} is {1}", ice.Name, ice.Price);     } Также можно использовать ArrayList для хранения объектов, как было использовано List. Запрос LINQ, в таком случае, можно использовать для получения конкретных объектов из коллекции в зависимости от потребности. Например, нижеследующий код для добавления тех же самых объектов Icecreams в ArrayList, как это делалось в предыдущем примере.     ArrayList arrListIcecreams = new ArrayList();     arrListIcecreams.Add( new Icecream {Name="Chocolate Fudge Icecream",         Ingredients="cream, milk, mono and diglycerides...",         Cholesterol="50mg", Protein="4g", TotalCarbohydrates="35g",         TotalFat="20g", Price=10.5 });     arrListIcecreams.Add( new Icecream {Name="Vanilla Icecream",         Ingredients="vanilla extract, guar gum, cream...",         Cholesterol="65mg", Protein="4g", TotalCarbohydrates="26g",         TotalFat="16g", Price=9.80 });     arrListIcecreams.Add( new Icecream {Name="Banana Split Icecream",         Ingredients="Banana, guar gum, cream...", Cholesterol="58mg",         Protein="6g", TotalCarbohydrates="24g", TotalFat="13g", Price=7.5     }); Следующий запрос выбирает недорогое мороженое из списка. var queryIcecreanList = from Icecream icecream in arrListIcecreams     where icecream.Price < 10     select icecream; Как будет показано ниже, можно использовать цикл для отображения цены объектов, извлеченных вышеуказанным запросом. foreach (Icecream ice in queryIcecreanList)     Console.WriteLine("Icecream Price : " + ice.Price); Чтение из строк Как известно, строка – набор символов. Т.е. можно запросить непосредственно строковое значение. Для примера можно рассмотреть случай, когда необходимо посчитать количество заглавных букв в строке aString: string aString = "Satheesh Kumar"; Далее строится запрос на чтение строки и нахождение количества заглавных букв. Тип запроса – IEnumerable. IEnumerable query =     from ch in aString     where Char.IsUpper(ch)     select ch; Запрос использует метод Char.IsUpper в условии where для нахождения букв в верхнем регистре из строки. Следующий код отображает количество символов, написанных в верхнем регистре в данной строке. Console.WriteLine("Count = {0}", count); Чтение из текстового файла Файл можно назвать коллекцией независимо от хранящихся в нем данных. Будет создан текстовый файл, содержащий некоторое количество строк. Для получения значений из текстового файла можно использовать запросы LINQ. В примере будет использован текстовый файл, содержащий названия разнообразных сортов мороженого. Для чтения каждой строки текстового файла можно использовать объект StreamReader. Для хранений значений, считанных из текстового файла, создается объект List. После записи в список значений, полученных из текстового файла, можно достаточно просто запросить список, используя LINQ, как было показано выше. В примере ниже рассмотрен код, считывающий строки из текстового файла и загружающий их в список строк. List IcecreamNames = new List();     using( StreamReader sReader = new StreamReader(@"C:Icecreams.txt"))     {         string str;         str = sReader.ReadLine();         while (str != null)         {             IcecreamNames.Add(str);         }     } В следующем коде считывается список строк и возвращаются названия мороженого, отсортированные по убыванию. IEnumerable icecreamQuery =     from name in IcecreamNames     orderby name descending     select name; Для проверки выполнения запроса можно вывести названия мороженого на дисплей, например, так foreach (string nam in icecreamQuery)     {         Console.WriteLine(nam);     } Следующий код выводит названия и проверяет результат работы запроса. foreach (string nam in icecreamQuery)     {         Console.WriteLine(nam);     } Как и коллекции, использованные в примерах выше, библиотека классов .NET может быть использована для чтения метаданных сборки .NET и создавать типы, члены типов, параметры, и другие свойства коллекции. Эти коллекции поддерживают интерфейс IEnumerable, который помогает запрашивать с использованием LINQ. LINQ имеет много стандартных операторов запросов, которые можно использовать для запроса разных объектов, поддерживающих IEnumerable. На этих объектах можно использовать все стандартные операторы запросов, перечисленные ниже. Тип оператора запросов Операторы запроса ограничение Where, OfType проекция Select, SelectMany присоединение Join, GroupJoin Конкатенация Concat Сортировка OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse установка Distinct, Except, Intersect, Union группировка GroupBy Преобразование AsEnumerable, Cast, OfType, ToArray, ToDictionary, ToList, ToLookup Сравнение SequenceEqual Выбор элемента DefaultIfEmpty, ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault образование Empty, Range, Repeat Количественное определение All, Any, Contains Агрегирование Aggregate, Average, Count, LongCount, Max, Min, Sum Разметка Skip, SkipWhile, Take, Takewhile   Итог В статья были рассмотрены некоторые примеры выполнения запросов с использованием операторов LINQ. LINQ можно использовать на любом объекте, поддерживающем интерфейс IEnumerable. Использование LINQ позволяет избежать использования циклических методов для получения необходимых данных из коллекции. LINQ предоставляет мощные методы для фильтрации, группировки и упорядочения данных. Использование LINQ позволит уменьшить объем исходного кода, тем самым ускорив время разработки. Источник: http://www.codedigest.com/Articles/CSHARP/218_LINQ_to_Objects_in_C_.aspx
Замыкание в C#

Автор: Редакция ITVDN

Введение Замыкание, как правило, используется функциональными языками программирования, где они связывают функцию с определенным типом параметров, это позволяет дать доступ к переменным, находящимся за пределами границы функции. С использованием делегатов замыкание доступно в С#.   Что такое Замыкание? Чаще всего, лексика замыкания используется в функциональных языках программирования. Замыкание – это специальный тип функции, с помощью которого она ссылается на свободные переменные. Это позволяет замкнутым функциям использовать переменные из внешнего окружения, несмотря на то что они не входят в границы. Когда функция создана, внешние переменные, которыми мы пользуемся, «захватываются», иными словами, они связаны с замкнутой функцией, так что они становятся доступными. Часто это обозначает то, что делаются копии значений переменных, когда инициализируется замыкание. Использование замыкания в С# В С#  замыкание может быть создано с помощью анонимного метода или лямбда-выражения, все зависит от версии .NET framework, на которой вы разрабатываете. Когда вы создаете функцию, переменные, что используются в ней и находятся за областью видимости, скопированы и хранятся в коде с замыканием. Они могут использоваться везде, где вы вызовете оператор delegate. Это дает огромную гибкость при использовании делегатов, но также создает возможность неожиданных багов. К этому мы вернемся позже. А пока, давайте рассмотрим простой пример замыкания. В коде, который ниже, мы создаем переменную «nonLocal» типа integer. Во второй строчке создаем экземпляр делегата «Action», что выводит в сообщение значение переменной типа integer. В конце мы запускаем функцию-делегат, чтобы увидеть сообщения.  int nonLocal = 1; Action closure = delegate { Console.WriteLine("{0} + 1 = {1}", nonLocal, nonLocal + 1); }; closure();  // 1 + 1 = 2 Мы можем сделать то же самое с лямбда-выражением. В следующем коде мы используем «lambda» для вывода информации, при этом лямбда-выражение имеет одинаковую силу. int nonLocal = 1; Action closure = () => {     Console.WriteLine("{0} + 1 = {1}", nonLocal, nonLocal + 1); }; closure();  // 1 + 1 = 2 Замыкания и переменные за пределами С помощью анонимных методов или лямбда-выражения примеры выше,при этом получаем те результаты, что вы могли ожидать, так как захват переменных замыканием не очевиден сразу же. Мы можем сделать его более явным, изменяя пределы делегатов. Рассмотрим следующий код. Здесь замыкание находится в классе «program» с переменной «action». В главном методе вызываем метод «SetUpClosure» для инициализации замыкания перед его использованием. Метод «SetUpClosure» очень важен. Вы можете увидеть, что переменная типа integer создана и инициализирована, и только тогда используется замыкание. В конце метода «SetUpClosure» эта переменная типа integer выходит за пределы. Однако, мы все еще вызываем делегат после этого. Скомпилируется и запустится ли этот код правильно? Произошло ли исключение при получении доступа к переменной за пределами? Попробуйте выполнить код. class Program {     static Action _closure;     static void Main(string[] args)     {         SetUpClosure();         _closure();     // 1 + 1 = 2     }     private static void SetUpClosure()     {         int nonLocal = 1;         _closure = () =>         {             Console.WriteLine("{0} + 1 = {1}", nonLocal, nonLocal + 1);         };     } } Вы могли заметить, что мы получили одинаковый результат как и в оригинальном примере. Это и есть замыкание в действии. Переменная «nonLocal» была охвачена или «замкнута» кодом delegate, в результате чего она остается в нормальных пределах. По сути, переменная будет доступна, пока никаких дальнейших ссылок на делегат не останется. Несмотря на то, что мы увидели замыкание в действии, они не поддерживаются С# и .NET framework. То, что действительно происходит - это работа на заднем фоне компилятора. Когда вы создаете собственные проекты, компилятор генерирует новые, скрытые классы, инкапсулируют нелокальную переменную и описанный код в анонимный метод или лямбда-выражение. Код, описанный в методе, и нелокальная переменная представлены в виде полей. Этот новый метод класса вызовется, когда делегат выполняется. Автоматически сгенерированный класс для нашего простого замыкания - аналогичный приведенному ниже: [CompilerGenerated] private sealed class <>c__DisplayClass1 {     public int nonLocal;     public void b__0()     {         Console.WriteLine("{0} + 1 = {1}", this.nonLocal, this.nonLocal + 1);     } } Замыкание захватывает переменную, а не его значение В некоторых языках программирования определяют значение переменной, которая используется в замыкании. В С# захватываются сами переменные. Это важное отличие, так как мы можем изменять значение переменной за пределами функции. Для иллюстрации рассмотрим следующий код. Здесь мы создаем замыкание, которое выводит наше начальное математическое значение переменной. При создании делегатов значение переменной типа integer равно 1. Но после того замыкания, как мы объявили замыкание, и перед тем, как его вызвали, значение переменной поменялось на 10. int nonLocal = 1; Action closure = delegate {     Console.WriteLine("{0} + 1 = {1}", nonLocal, nonLocal + 1); }; nonLocal = 10; closure(); Так как нелокальная переменная имела значение 1 перед созданием замыкания, вы могли бы ожидать, что результатом вывода будет «1+1=2». На самом деле, на других языках программирования так бы и было. Однако, так как мы изменили значение переменной до вызова функции замыкания, это значение влияет на выполнение функции замыкание. В действительности, вы увидите на дисплее: 10 + 1 = 11 Изменения в нелокальную переменную внутри функции замыкания также передаются в другом направлении. В следующем коде внутри делегата изменяем значение переменной перед тем, как объявленный код выведет ее. Изменения видны во внешней части кода несмотря на то, что происходят они внутри замыкания.  int nonLocal = 1; Action closure = delegate {     nonLocal++; }; closure(); Console.WriteLine(nonLocal);    // 2 Переменная, которую мы изменяем, может привести нас к неожиданным багам в нашем коде. Мы можем продемонстрировать эту проблему в другом примере. На этот раз мы используем замыкание в простом алгоритме: многопоточное или параллельное программирование. Код ниже показывает цикл for, который имеет 5 новых потоков. Каждая пауза короткая, перед выводом значения переменной внутри цикла. Если значение переменной в цикле были захвачены, мы увидим цифры от 1 до 5 показаны в консоли, хотя, возможно, не в правильном порядке. Однако, так как эта переменная находится внутри замыкания и цикл закончится до того, как переменные будут выведены в сообщение, в конечном итоге мы увидим значение 6 для каждого потока.  for(int i = 1; i <= 5; i++) {     new Thread(delegate()     {         Thread.Sleep(100);         Console.Write(i);     }).Start(); } // Outputs "66666" К счастью, такая проблема легко устраняется, когда вы понимаете, что переменные, а не их значения захватываются. Все, что нам нужно сделать, это создать новую переменную для каждого прохождения(итерации) цикла. Это объявление можно записать в теле цикла и давать значение в управляющую переменную. При нормальных обстоятельствах временная переменная будет находится за переделами, когда цикл закончится, но замыкание будет связывать и поддерживать ее. В коде ниже вы можете увидеть 5 примеров «значений», переменные, созданные и им назначенные 5 различных значений, каждая из них привязана к разному потоку. for(int i = 1; i <= 5; i++) {     int value = i;     new Thread(delegate()     {         Thread.Sleep(100);         Console.Write(value);     }).Start(); } // Outputs "12345" Обратите внимание: вывод может меняться в зависимости от порядка, в котором потоки выполняются. Источник: http://www.blackwasp.co.uk/CSharpClosures.aspx
C# How To: Как открыть PDF файл с помощью C#

Автор: Редакция ITVDN

Введение Во время разработки мы добавим контроль WebBrowser в форму. При запуске программы используем следующий код для того, чтобы открыть PDF-файл в элементе управления WebBrowser. // Display the PDF file. private void Form1_Load(object sender, EventArgs e) {     string filename = Application.StartupPath;     filename = Path.GetFullPath(         Path.Combine(filename, ".\\Test.pdf"));     wbrPdf.Navigate(filename); } Во время разработки добавим этот файл к проекту и установим его "Copy to Output Directory" свойство "Copy if newer", так что файл будет в каталоге исполняемой программы. Этот код получает каталог запуска программы и добавляет имя файла test.pdf. Затем заставляет управление WebBrowser wbrPdf перейте к этому файлу. Источник: http://csharphelper.com/blog/2015/11/open-a-pdf-file-in-c/
Notification success