C# — Подборщик на c#


Сборщик данных с сайта

15.11.2010, 20:10

Сборщик мусора
Здравствуйте, есть такая проблема. Идет работа с прибором, который в реальном времени шлет данные.

Существует ли в C# сборщик мусора
Подскажите пожалуйста, а когда мы создаем экземпляр формы, его надо потом как то уничтожать при.

Сборщик мусора не удаляет объект
Сборщик мусора не удаляет объект. Мне необходимо чтобы GC его удалил, но этого не происходит.

Загадка про сборщик мусора
Однажды мне в голову пришла такая идея, и решил спросить мнения у опытных людей. Итак, логика.

Рациональное использование памяти, сборщик мусора
Задача определить такую структуру данных: Entity — Мешок для компонентов. Есть массив.

Как подружить C++ и C# через COM наиболее простым способом?

Все рецепты использования COM включают в себя создание библиотеки типов, ее регистрацию в реестре, регистрацию в реестре сервера.

В DLL-ке при этом надо создавать фабрику объектов.

Если есть исполнимый файл на C# и DLL на C++ — можно ли обойтись безо всех этих шагов и просто загрузить dll-ку?

3 ответа 3

Да, можно. Технология COM не требует для своего использования какой бы то ни было регистрации в реестре!

Все перечисленные в вопросе шаги нужны для уменьшения связности модулей. Если вам эти шаги не подходят, не нужны или вам просто лень их делать — их можно пропустить.

Вот работающий минимальный пример.

В примере выше интерфейсы на двух языках были составлены независимо. В принципе, это является двойной работой — поэтому имеет смысл составить интерфейс только 1 раз, после чего его импортировать.

Если интерфейс составляется в C++-проекте на языке IDL — то достаточно потом подключить библиотеку типов в C#-проект как зависимость. Регистрировать ее при этом не обязательно!

Если интерфейс составляется в C#-проекте, то надо обязательно поставить ему кроме перечисленных выше атрибут Guid и сделать его публичным. После этого можно вытащить библиотеку типов через tlbexp и подключить в C++-проект. Регистрировать библиотеку типов в реестре, опять-таки, не требуется.

Главное в .NET — Написание скриптов на C#

С выходом Visual Studio 2015 Update 1 (далее для краткости Update 1) появился новый C# REPL (read-evaluate-print-loop), доступный как новое интерактивное окно в Visual Studio 2015 или как новый интерфейс командной строки (command-line interface, CLI), названный CSI. В дополнение к существующему языку C# в командной строке Update 1 также вводит новый скриптовый язык C#, традиционно сохраняемый в CSX-файл.

Прежде чем погружаться в детали новой поддержки написания скриптов на C#, важно понимать целевые сценарии. Поддержка скриптов на C# — это средство для тестирования ваших фрагментов кода на C# и .NET, не прикладывая усилия к созданию множества проектов модульного тестирования или консольных проектов. Она предоставляет облегченный вариант для быстрого кодирования вызова LINQ-метода агрегации в командной строке, проверки .NET API для распаковки ZIP-файлов или вызова REST API для прояснения того, что он возвращает или как он работает. Вы получаете простые средства для исследования и понимания какого-либо API без издержек появления еще одного CSPROJ-файла в вашем каталоге %TEMP%.

Интерфейс командной строки C# REPL (CSI.EXE)

Как и при изучении самого C#, лучший способ начать освоение интерфейса C# (CSI) REPL — запустить его и приступить к выполнению команд. Для запуска интерфейса, введите команду csi.exe из командной строки Visual Studio 2015 или используйте полный путь C:\Program Files (x86)\MSBuild\14.0\bin\csi.exe. Отсюда начнется выполнение выражений C# по аналогии с тем, что показано на рис. 1.

Рис. 1. Пример CSI REPL

Первым делом отмечу очевидное — он похож на C#, хоть и на новый диалект C# (но без формальностей, которые ценятся в полностью производственной программе и не обязательных в сделанном на скорую руку прототипе). Поэтому, как и следовало ожидать, если вы хотите вызвать какой-нибудь статический метод, то можете написать полное имя метода и передать аргументы внутри скобок. Как и в C#, вы объявляете переменную, предваряя ее типом и (не обязательно) присваивая ей новое значение в момент объявления. И вновь, как и следовало ожидать, нормально работает любой допустимый синтаксис тела метода — блоки try/catch/finally, объявление переменных, лямбда-выражения и LINQ.

И даже в командной строке поддерживаются другие средства C# вроде строковых конструкций (чувствительность к регистру букв, строковые литералы и интерполяция строк). Поэтому, когда вы используете или выводите пути, для каждого обратного слеша нужно ставить escape-символ C# (\), как это делается двойными обратными слешами в пути запуска csi.exe. Интерполяция строк тоже работает, что демонстрирует пример строки «текущего каталога» на рис. 1.

Однако поддержка скриптов в C# позволяет делать гораздо больше, чем просто набирать выражения в командной строке. Вы можете объявлять собственные типы, встраивать метаданные типа через атрибуты и даже упрощать вывод, используя специфичные для скриптов на C# директивы. Рассмотрим пример с проверкой правописания на рис. 2.

Рис. 2. Скриптовый C#-класс Spell (Spell.csx)

По большей части это просто стандартное объявление C#-класса. Однако здесь есть несколько специфичных для скриптов на C# средств. Во-первых, директива #r служит для ссылки на внешнюю сборку. В данном случае это ссылка на Newtonsoft.Json.dll, которая помогает разбирать JSON-данные. Но заметьте, что эта директива предназначена для ссылок на файлы в файловой системе. Как таковая, она не требует лишних формальностей с escape-символами для обратных слешей.

Во-вторых, вы можете взять весь этот листинг и сохранить его как CSX-файл, а затем «импортировать» или «подставить» (inline) файл в окно C# REPL, используя #load Spell.csx. Директива #load позволяет включать дополнительные файлы скриптов так, будто все #load-файлы были включены в один и тот же «проект» или «компиляцию». Размещение кода в отдельном файле C#-скрипта обеспечивает своего рода рефакторинг файла и, что важнее, возможность хранить C#-скрипт.

Использование объявлений — еще одно языковое средство C#, включенное в скрипты C#; оно несколько раз используется в коде на рис. 2. Заметьте, что, как и в C#, область объявления using ограничена файлом. Поэтому, если вы вызвали #load Spell.csx из окна REPL, объявление using Newtonsoft.Json не сохранится за пределами Spell.csx. Иначе говоря, использование Newtonsoft.Json из Spell.csx не сохранилось бы в окне REPL без его повторного явного объявления в окне REPL (и наоборот). Также заметьте, что поддерживается и объявления using static из C# 6.0. Благодаря этому объявление using static System.Console исключает необходимость предварять любой из членов System.Console типом, разрешая выполнение таких REPL-команд, как WriteLine(«Hello! My name is Inigo Montoya»).

Другие конструкции, заслуживающие внимания в скриптах на C#, включают атрибуты, выражения using, объявление свойства и функции и поддержку async/await. Учитывая поддержку последнего функционала, await можно использовать даже в окне REPL:

Ниже дан ряд дополнительных замечаний по интерфейсу C# REPL.

  • Запустить csi.exe из Windows PowerShell Integrated Scripting Environment (ISE) нельзя, так как эта программа требует прямого консольного ввода, что не поддерживается имитируемыми консольными окнами Windows PowerShell ISE. (По этой причине подумайте о ее добавлении в список неподдерживаемых консольных приложений $psUnsupportedConsoleApplications.)
  • Команды exit или quit для выхода из CSI-программы нет. Вместо этого используйте Ctrl+C для завершения программы.
  • Журнал команд (command history) сохраняется между сеансами работы с csi.exe, запускаемыми из одного и того же сеанса cmd.exe или PowerShell.exe. Например, если вы запускаете csi.exe, вызываете Console.WriteLine(«HelloWorld»), используете Ctrl+C для выхода, а затем снова запускаете csi.exe, нажатие стрелки вверх покажет предыдущую команду: Console.WriteLine(«HelloWorld»). Выход из окна cmd.exe с последующим перезапуском очистит журнал команд.
  • Csi.exe поддерживает REPL-команду #help, которая дает вывод, показанный на рис. 3.
  • Csi.exe поддерживает ряд параметров в командной строке, как представлено на рис. 4.

Рис. 3. Вывод REPL-команды #help

Рис. 4. Параметры командной строки csi.exe

Для верстки: в этом листинге не обойтись без наезда на соседнюю колонку, иначе будет сильное искажение вывода

Как отмечалось, csi.exe позволяет указывать файл «профиля» по умолчанию, который настраивает ваше окно команд.

  • Чтобы очистить консоль CSI, вызовите Console.Clear. (Подумайте насчет директивы using static System.Console для добавления поддержки вызова просто Clear.)
  • Если вы вводите команду, занимающую несколько строк, и обнаруживаете ошибку на одной из предыдущих строк, то можете использовать Ctrl+Z с последующим нажатием Enter для отмены и возврата к пустой строке приглашения без выполнения (заметьте, что в консоли появится ^Z).

Окно C# Interactive в Visual Studio

Как упоминалось, в Update 1 появилось и новое окно C# Interactive (рис. 5). Это окно запускается через View | Other Windows | C# Interactive и открывается как дополнительное стыкуемое окно. Как и окно csi.exe, это окно C# REPL, но с несколькими дополнительными средствами. Прежде всего оно включает цветовое выделение синтаксиса кода и поддержку IntelliSense. Аналогично компиляция выполняется в реальном времени по мере того, как вы редактируете код, поэтому синтаксические ошибки и другие огрехи автоматически подчеркиваются волнистой красной линией.

Рис. 5. Объявление скриптовой функции C# вне класса, использующего окно C# Interactive в Visual Studio

Окно C# Interactive, конечно, сразу же ассоциируется с окнами Immediate и Command в Visual Studio. Хотя они перекрываются по своей функциональности (в конце концов, это REPL-окна, в которых вы выполняете .NET-выражения), они имеют существенно разное предназначение. Окно C# Immediate прямо связано с отладочным контекстом вашего приложения, тем самым позволяя вводить дополнительные выражения в контекст, изучать данные в сеансе отладки и даже манипулировать/обновлять данные и отладочный контекст. Аналогично окно Command предоставляет CLI для манипуляций над Visual Studio, включая выполнение различных меню, но не из самих меню, а из окна Command. (Например, выполнение команды View.C#Interactive открывает окно C# Interactive.) В противоположность этому окно C# Interactive позволяет выполнять C#, включая все средства, относящиеся к интерфейсу C# REPL, рассмотренному в предыдущем разделе. Однако окно C# Interactive не имеет доступа к отладочному контексту. Это полностью зависимый сеанс C# без описателей (handles) отладочного контекста или даже Visual Studio. Подобно csi.exe это среда, которая позволяет экспериментировать с фрагментами кода на C# и .NET для проверки вашего понимания без запуска еще одного консольного проекта или проекта модульного тестирования Visual Studio. Но вместо запуска в отдельной программе окно C# Interactive размещается в Visual Studio, где предположительно уже находится разработчик.

Ниже приведено несколько замечаний по окну C# Interactive.

  • Оно поддерживает ряд дополнительных REPL-команд, отсутствующих в csi.exe, в том числе:
    • #cls/#clear для очистки содержимого окна редактора;
    • #reset для восстановления среды выполнения до ее начального состояния с сохранением журнала команд.
  • Клавиатурные комбинации немного неожиданные, как показывает вывод #help в табл. 1.

Табл. 1. Комбинации клавиш, действующие в окне C# Interactive

Enter Если текущее выражение полное, оно оценивается. В ином случае вставляется новая строка
Ctrl+Enter Оценивается текущее выражение
Shift+Enter Вставка новой строки
Esc Очистка текущего выражения
Alt+стрелка вверх Замена текущего выражения предыдущим
Alt+стрелка вниз Замена текущего выражения последующим (если ранее был переход назад)
Ctrl+Alt+стрелка вверх Замена текущего выражения предыдущим, начинающимся с того же текста
Ctrl+Alt+стрелка вниз Замена текущего выражения последующим, начинающимся с того же текста (если ранее был переход назад)
Стрелка вверх В конце текущего выражения его замена предыдущим. В ином случае перемещение курсора на строку вверх
Стрелка вниз В конце текущего выражения его замена последующим (если ранее был переход назад). В ином случае перемещение курсора на строку вниз
Ctrl+K, Ctrl+Enter Вставка выделенного блока в конец интерактивного буфера; «каретка» остается в в конце ввода
Ctrl+E, Ctrl+Enter Вставка и выполнение выделенного блока до любого незавершенного ввода в интерактивном буфере
Ctrl+A При первом нажатии выделяет выражение, в котором находится курсор. При втором нажатии выделяет весь текст в окне

Важно отметить, что Alt+стрелка вверх/вниз — это комбинации клавиш для вызова журнала команд. Microsoft выбрала эти комбинации вместо более простых «стрелка вверх/вниз», поскольку хотела, чтобы окно Interactive работало так же, как и стандартное окно кода в Visual Studio.

  • Поскольку окно C# Interactive размещается в Visual Studio, в нет тех же возможностей передачи ссылок, использования директив или импорта через командную строку, как в случае csi.exe. Вместо этого окно C# Interactive загружает свой контекст выполнения по умолчанию из C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\CSharpInteractive.rsp, который идентифицирует сборки для ссылок по умолчанию:

Более того, файл CSharpInteractive.rsp ссылается на файл C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\SeedUsings.csx по умолчанию:

Комбинация этих двух файлов является причиной того, что вы используете Console.WriteLine и Environment.CurrentDirectory вместо полных System.Console.WriteLine и System.Environment.CurrentDirectory соответственно. Кроме того, ссылки на сборки, такие как Microsoft.CSharp, позволяют использовать языковые средства вроде dynamic безо всяких дополнительных усилий. (Модификация этих файлов дает возможность изменять ваш «профиль» или «предпочтения» так, чтобы эти изменения сохранялись между сеансами.)

Подробнее о синтаксисе скриптов на C#

Один из моментов, которые следует учитывать в отношении синтаксиса C#-скриптов, заключается в том, что большая часть формальностей, важных в стандартном C#, становится соответственно не обязательной в C#-скрипте. Например, такие вещи, как тела методов не обязаны находиться в какой-либо функции, а функции C#-скрипта можно объявлять вне границ какого-либо класса. Скажем, вы могли бы определить NuGet-функцию Install, которая появляется непосредственно в REPL-окне, как показано на рис. 5. Кроме того, возможно, несколько неожиданно, C#-скрипты не поддерживают объявления пространств имен. Например, вы не можете обернуть класс Spell в пространство имен Grammar: namespace Grammar < class Spell <>>.

Важно отметить, что вы можете объявлять одну и ту же конструкцию (переменную, класс, функцию и т. д.) снова и снова. Последнее объявление следует любому более раннему объявлению.

Другой важный момент, о котором нужно знать, — поведение точки с запятой, завершающей команду. Операторы (например, присваивания переменных) требуют точки с запятой. Без нее REPL-окно будет по-прежнему предлагать дальнейший ввод (через точку), пока не будет введена точка с запятой. С другой стороны, выражения будут выполняться без точки с запятой. Следовательно, System.Diagnostics.Process.Start(«notepad») запустит Notepad даже без концевой точки с запятой. Более того, поскольку вызов метода Start возвращает процесс, в командной строке появится строковый вывод выражения: [System.Diagnostics.Process (Notepad)]. Но закрытие выражения точкой с запятой скроет этот вывод. Поэтому вызов Start с концевой точкой с запятой не даст никакого вывода, хотя Notepad все равно будет запущен. Конечно, Console.WriteLine(«It would take a miracle.»); будет по-прежнему выводить текст, даже без точки с запятой, поскольку вывод отображает сам метод.

Выражения (expressions) и операторы (statements) иногда имеют тонкие отличия. Например, оператор string text = «There’s a shortage of perfect b….»; не даст никакого вывода, а text=»Stop that rhyming and I mean it» вернет присвоенную строку (поскольку присваивание возвращает присвоенное значение и в конце нет точки с запятой, которая подавила бы вывод).

Директивы в C#-скриптах для ссылок на дополнительные сборки (#r) и импорт существующих C#-скриптов (#load) — великолепные новшества. К сожалению, на момент написания этой статьи NuGet-пакеты не поддерживались. Для ссылки на файл из NuGet требуется установить этот пакет в каталог, а затем сослаться на конкретную DLL через директиву #r. (В Microsoft меня уверили, что вскоре необходимая поддержка появится.)

Заметьте, что на этот раз директивы ссылаются на конкретные файлы. Указать в директиве, например, какую-то переменную нельзя. Хотя этого и следовало ожидать, это исключает возможность динамической загрузки сборки. Скажем, вы могли бы динамически запускать nuget.exe install для извлечения сборки (вновь см. рис. 5). Однако тогда ваш CSX-файл было бы нельзя динамически связать с извлеченным NuGet-пакетом, так как нет никакого способа динамически передавать путь сборки в директиву #r.

C# CLI

Должен признаться, что у меня двоякое отношение к Windows PowerShell. Мне нравится удобство работы с Microsoft .NET Framework в командной строке и возможность передачи .NET-объектов по конвейеру, а не традиционного текста, как это делается во многих других CLI. Когда дело доходит до языка C#, я становлюсь пристрастен: обожаю его элегантность и мощь. (До сих пор я остаюсь под впечатлением от языковых расширений, которые сделали возможной работу с LINQ.) Поэтому идея сочетания свободы действий в Windows PowerShell .NET с элегантностью языка C# наводила на мысль, что C# REPL может быть заменой Windows PowerShell. После запуска csi.exe я сразу же опробовал команды вроде cd, dir, ls, pwd, cls, alias и им подобные. Достаточно сказать, что я был разочарован, так как ни одна из них не работала. После раздумий и обсуждения с группой C# я осознал, что замена Windows PowerShell не была в числе задач, на которых группа сосредоточилась в версии 1. Более того, это .NET Framework, а значит, она поддерживает расширяемость добавлением ваших собственных функций для предыдущих команд и даже обновлением реализации C#-скрипта в Roslyn. Я немедленно приступил к определению функций для таких команд. Получившаяся в итоге библиотека в своем начальном виде доступна для скачивания на GitHub по ссылке github.com/CSScriptEx.

Для тех, кто ищет более функциональный C# CLI, который изначально поддерживает предыдущий список команд, присмотритесь к ScriptCS на scriptcs.net (или на GitHub по ссылке github.com/scriptcs). Он тоже использует Roslyn и включает поддержку псевдонимов, команд cd, clear, cwd, exit, help, install, reset, ссылок, пакетов скриптов, выражений using и var. Заметьте, что в случае ScriptCS префиксом команд сегодня является двоеточие (как в :reset), а не символ # (как в #reset). В качестве бонуса ScriptCS также добавляет поддержку CSX-файлов с цветовым выделением и IntelliSense в Visual Studio Code.

Заключение

По крайней мере пока целью интерфейса C# REPL не является замена Windows PowerShell или даже cmd.exe. Ожидание этого приведет к разочарованию. Вместо этого я предлагаю относиться к C#-скриптам и различным REPL CLI как к облегченным заменам Visual Studio | New Project: UnitTestProject105 или к аналогам на dotnetfiddle.net. Это способы, ориентированные на C# и .NET, должны углубить ваше понимание языка и .NET API. C# REPL предоставляет средства для кодирования коротких фрагментов или блоков программы, с которыми вы можете поэкспериментировать, пока они не будут готовы для вставки в более серьезные программы. Это позволяет вам писать более содержательные скрипты, чей синтаксис проверяется «на лету» в процессе написания кода (вылавливаются даже такие мелкие ошибки, как неправильный регистр букв), и вас не вынуждают запускать скрипт только для того, чтобы обнаружить, что вы где-то опечатались. Как только вы это поймете, поддержка скриптов на C# и ее интерактивные окна станут приятным инструментом, который вы искали с момента появления первой версии языка.

Как бы ни были интересны C# REPL и поддержка скриптов на C# сами по себе, считайте, что они также являются плацдармом инфраструктуры расширения для ваших приложений — а-ля Visual Basic for Applications (VBA). Благодаря интерактивному окну и поддержке скриптов на C# вы можете вообразить мир (не столь уж и несбыточный), в котором вновь можно добавлять в приложения «макросы», но уже относящиеся к .NET, — без изобретения собственного языка, средства синтаксического анализа и редактора.

Марк Михейлис (Mark Michaelis) — учредитель IntelliTect, где является главным техническим архитектором и тренером. Почти два десятилетия был Microsoft MVP и региональным директором Microsoft с 2007 года. Работал в нескольких группах рецензирования проектов программного обеспечения Microsoft, в том числе C#, Microsoft Azure, SharePoint и Visual Studio ALM. Выступает на конференциях разработчиков, автор множества книг, последняя из которых — «Essential C# 6.0 (5th Edition)» (itl.tc/EssentialCSharp). С ним можно связаться в Facebook (facebook.com/Mark.Michaelis), через его блог (IntelliTect.com/Mark), в Twitter (@markmichaelis) или по электронной почте mark@IntelliTect.com.

Выражаю благодарность за рецензирование статьи экспертам Microsoft Кевину Босту (Kevin Bost) и Кейси Олинхуту (Kasey Uhlenhuth).

Цукерберг рекомендует:  Как начать карьеру, работая удалённо

Нехитрые Советы для программиста C#

1. Довольно часто нужно вернуть в коде истину , если число положительное , и ложь , если число отрицательное. Тогда , вместо того , чтобы писать что-то вроде этого :

public static bool TruOrFls (int i )

. можно написать такой простой код :

public static bool TruOrFls( int i)

2. Для определения , является ли целое число чётным или нечётным , можно использовать сл. метод :

public static bool IsNechet( int i)

Math .DivRem(i, 2, out result);

3. Простой класс для Шаблона «Одиночка » (Singleton) для создания форм :

public static class SingletonForm

private static Dictionary Type , Form > forms = new Dictionary Type , Form >();

public static Form ShowInstance( Type t)

Form f = ( Form ) Activator .CreateInstance(t);

f.Disposed += new EventHandler (f_Disposed);

static void f_Disposed( object sender, EventArgs e)

public void btnsprTIP_Click(System. Object sender, System. EventArgs e)

SingletonForm .ShowInstance( typeof ( frmMyForm ));

4 . Для «отлавливания» неверно введённого символа в сетке( DataGr >можно использовать событие DataError :

public void MyDtg_DataError( object sender, DataGridViewDataErrorEventArgs anError)

int ColIndx = ( int )anError.ColumnIndex;

string ColHT = MyDtg.Columns[ColIndx].HeaderText;

Utils .Mess( » » + ColHT + » !» );

5. Помещайте формы , классы , отчёты и т д. проекта в соответствующие подкаталоги с именами , например , FRM, CLS, RPT и т.д. Такая систематизация существенно облегчит вашу жизнь при работе с большими проектами. Мешанина из классов , форм , отчётов и пр. в одном подкаталоге вряд ли пойдёт на пользу качеству вашего проекта.

6. Если нужно постоянно обращаться к какому-то объекту ( или что-то возвращать из метода без передачи параметра внутрь его) , то такую функцию удобно осуществлять с помощью аксессора get . Например , сл. код возвращает текущую строку в DataGrid View:

public DataGridViewRow GetCurrentRowOb

К такому методу можно обращаться просто как к переменной.

7. Вы можете назначить свою обработку какого-либо события в конструкторе сл. образом :

/* Альтернативная обработка события */

this .txtHr.KeyPress += new KeyPressEventHandler ( this .ObrabKey);

В приведённом примере назначаем метод обработки ObrabKey событию KeyPress

8. Технология LINQ может существенно сократить количество ваших клацаний по клавиатуре. Например сл. код возвращает отсортированный массива :

public static string [] GetStr

public static IEnumerable string > SortedList

IEnumerable string > sort = GetStr.OrderBy(a => a.j);

9. Несложные классы (особенно если используется их большое количество экземпляров) лучше оформлять в виде структур — ключевое слово struct . Структура , в отличии от класса , является значимым типом. Экономия ресурсов , в этом случае , может оказаться весьма существенной.

10 . Довольно часто приходиться итерировать объекты , которые не поддерживают интерфейс IEnumarable. Чтобы избежать это ограничение , существует специальная конструкция — yeild. Ниже приведён пример , как можно проитерировать коллекцию упр. элементы на главной форме :

class Num : IEnumerable

frmMain MyF = GlobalVar .MainForm;

public System.Collections. IEnumerator GetEnumerator()

yield return MyF.Panel1;

yield return MyF.Panel2;

yield return MyF.Panel3;

yield return MyF.panel6;

yield return MyF.GroupBox1;

yield return MyF.groupBox2;

yield return MyF.GroupBox3;

yield return MyF.TableLayoutPanel1;

yield return MyF.pictureBox1;

Вот теперь можно пробежаться в цикле -применение в вызывающей стороне :

foreach ( Control cob in new Num ())

cob.Anchor = AnchorStyles .Right;

11. Использование конструкции using ( . ) < . >гарантирует применение метода . Dispose() — освобождение объекта , например :

using ( SqlCommand cmd = new SqlCommand (strSQL, GlobalVar .conn))

// Здесь что-то делаем с объектом cmd .

// Это нужно делать , если не использовать using (. )

1 2 . При работе с базами данных обязательно напишите класс с методами создания соединения с БД и его тестированием , что-то вроде этого :

static class clsConn

public static void CreateConn( string strmydir)

GlobalVar .conn = new SqlConnection (ConnectStringBuild);

Utils .Mess( » Ошибка !» );

public static bool TestConn

using ( SqlConnection testconn = new SqlConnection (ConnectStringBuild))

return (testconn.State == ConnectionState .Open);

// Создание строки подключения к БД .

public static string ConnectStringBuild

string s = «Data Source=» + My. Settings .Default.ServerName + @»\» + My. Settings .Default.SQLServerName + «;» ;

return @s += «Initial Catalog=» + My. Settings .Default.BaseName + «;Integrated Security=True» ;

13. Включите обработку ошибок в стартовый модуль вашей программы. Выше него ошибка » не поднимется «( выше только Господь Бог :-). Что-то вроде этого :

sealed class mdlMain

public static void Main( string [] args)

Application .SetCompatibleTextRenderingDefault( false );

GlobalVar .MainForm = new frmMain ();

Application .Run( GlobalVar .MainForm);

catch ( ArgumentNullException ane)

MessageBox .Show(ane.Message, » Main-ArgumentNullException» );

catch ( FormatException fex)

MessageBox .Show(fex.Message, » Main-FormatException» );

catch ( NullReferenceException nre)

MessageBox .Show(nre.Message, » Main-NullReferenceException» );

catch ( InvalidCastException ice)

MessageBox .Show(ice.Message, » Main-InvalidCastException» );

catch ( Exception ex)

MessageBox .Show(ex.Message , » o Main» );

14. Если в программе постоянно приходиться обрабатывать неизменяемый массив строк , то инициализацию такого массива очень удобно оформить с помощью аксессора get ( см. Совет 6 ) , что-то вроде этого :

private static string [] GetStringArr

string [] ars = new string [] <

Тогда подсчитать , например , количество элементов в массиве очень просто :

int RecCount1 = GetStringArr.Count();

Или , обращение к j- му элементу массива :

string s = GetStringArr[j-1];

15. Довольно часто в коде нужно контролировать — является ли значение пустым , и вернуть , ну допустим , значение нуль для типа float. Осуществить такую проверку можно с помощью такого нехитрого метода :

public static float CheckIt( object par)

return ( Convert .ToSingle( Convert .IsDBNull(par) ? 0 : par));

16. Если нужно знать , в каком столбце сетки DataGridView пользователь завершил редактирование ячейки , то можно использовать событие _CellEndEdit:

public void MyDtg_CellEndEdit( object sender, DataGridViewCellEventArgs e)

// Узнаём имя столбца .

string ColName = MyDtg.Columns[e.ColumnIndex].Name;

/* Здесь что-то делаем . */

17. Чтобы ‘ пробежаться ‘ по всем контролам в панели , и отловить , ну скажем , метки ( Label ) можно использовать такой код :

foreach ( Control cob in this .panel 1 .Controls)

if (cob is Label )

/* Здесь что-то делаем с контролом типа Label */

18. К строковой переменной можно смело «приклеивать » целочисленные переменные. Среда CLR поймёт такое преобразование без метода ToString(). Это особенно бывает удобно при формировании SQL— запросов в виде строк , что-то вроде этого :

string sSQL= «Update Itogi SET Area=@area where kod=» + (i + 1);

19. ‘Склеивать’ строки лучше специально созданным для этого методом Concat для переменных типа string :

string s3 = «three» ;

// Можно делать так :

string sAll = s1+s2+s3;

// . но грамотнее так :

string sAll = string .Concat(s1,s2,s3);

20. П рограммисты как-то недооценивают удобство метода Format для строк при формировании SQL-запросов . Например, вместо того, чтобы писать что-то вроде этого:

// Можно делать так :

string strUpdate = «Update Customers SET Balance=@Balance Where Cust > + >» and Social > + SocID;

. лучше написать такой код:

string strUpdate = «Update Customers SET Balance=@Balance Where Cust >;

string strSQLUpdate = string. Format( «<0> <1>and Social >, strUpdate, ID, SocID);

21. Иногда бывает нужно узнать индекс элемента в массиве, ну например, в цикле foreach . Сделать это можно сл. образом :

// Есть массив строк .

private static string [] GetStr

string [] ars = new string [] <

// В вызывающей стороне :

// Конечно , можно использовать счётчик .

foreach ( string s in GetStr)

private static void Sub()

foreach ( string s in GetStr)

//Узнаём индекс элемент а s в массиве .

int i = Array .IndexOf(GetStr, s);

22. Везде, где можно, предпочтительнее использовать типизированные коллекции, вместо классических массивов. Основные преимущества такого подхода заключаются в двух фактах: во-первых, коллекции позволяют не заботиться о контроле за выходом индекса за установленный размер ( пресловутое Index Out of Range), а во-вторых, в них можно хранить (в отличии от нетипизированных списков) элементы одного типа. Итак, вместо использования скажем:

string [] ars = new string [6];

. предпочтительнее использовать типизированный список List string >:

List string > ars = new List string >();

Небольшая ремарка. Вообще , на мой взгляд , в связи с появлением начиная , по-моему , с . NET Framework 2.0 типизированных коллекций , классические массивы можно считать коллекциями устаревшего типа по причинам , указанным выше

23. Если в метод надо передавать много-много всяких входных параметров, то вместо такого «баяна» предпочтительнее передавать структуру.

Например, вместо использования некоего метода XYZ

static void XYZ( int a, int b, int c, string d, string e)

. .. можно сначала определить структуру:

public string d,e;

public ABC ( int _a, int _b, int _c, string _d, string _e)

a=_a; b=_b; c=_c; d=_d; e=_e;

. а затем передавать её в метод :

static void XYZ( ABC mystru)

Вызов такого метода станет гораздо более изящным:

/* Определяем экземпляр структуры ABC */

ABC MyStru = new ABC (1,2,3,»one», «two»);

/*Вызываем метод XYZ */

24. Довольно часто программисты пользуются методом Parse для конвертации строковых величин в другие типы, что-то вроде этого:

int j= int .Parse (MyVal.ToString());

Однако, в случае неудачи такой метод выбросит исключение. Для написания устойчивого кода предпочтительнее пользоваться метод TryParse, приблизительно так:

/* Вернёт значение j=0, даже если метод TryParse потерпит неудачу */

bool bVal = int .TryParse(MyVal.ToString(), out j);

25 . Самый подходящий элемент для отображения содержания базы данных — это конечно же DataGr >, упрощенно говоря, сетка данных . Но после завершения редактирования данных пользователем в такой сетке встаёт задача — как передать изменения в базу данных ? Одно из решений такой задачки состоит в переписывании (в цикле естественно) значений ячеек сетки DataGridViewCell в значения объекта DataRow , привязанного к сетке объекта DataTable набора данных DataSet . Тут, правда, надо хорошо разбираться в идеологии объектной модели доступа к данным ADO. NET . Затем значения DataRow конкретного столбца переписываем SQL-конструкцией Update непосредственно в базу данных. Все циклы здесь можно прогонять конструкцией foreach

26 . Иногда возникает сл. ситуация. На форме есть куча однотипных элементов WinForms, одно и тоже событие которых обрабатывается одинаково. Как пример, есть несколько элементов TextBox, для которых событие, ну скажем, KeyPress обрабатывается одним и тем же методом.

Тогда, вместо такого забойного кода . :

public void txt box1 _KeyPress( object sender, KeyPressEventArgs e)

ObrabKeyPress ( sender, e );

public void txt box 2_KeyPress( object sender, KeyPressEventArgs e)

ObrabKeyPress ( sender, e );

public void txt boxN _KeyPress( object sender, KeyPressEventArgs e)

ObrabKeyPress ( sender, e );

. можно сначала определить массив TextBox’ов :

private TextBox [] RetTBox

. а затем, скажем в конструкторе формы, прокрутить такой цикл :

/* Добавляем свой обработчик контроля нажатия клавиш */

foreach ( TextBox tb in RetTBox)

tb.KeyPress += new KeyPressEventHandler (ObrabKeyPress);

27 . У объекта ADO.Net Reader есть один весьма полезный метод — HasRows. Он возвращает значение true , если в запросе есть данные.

Проконтролировать наличие ‘ пустого ‘ Reader’ а в это случае становиться довольно легко :

using ( SqlCommand SelCustoms = new SqlCommand (sSel, conn2))

//Нет записей о заказчиках ! Прекращаем читать ..

// Пробежимся по всем записям Заказчиков .

// . Здесь что-то читаем Reader’ом

28 . Хорошей альтернативой созданию параметров в простых SQL- запросах ( объект Parameters) может стать использование строки запроса методом string .Format ( см. Совет 20 ) , что-то вроде этого :

string sSQL = string .Format( «Select * From Customers where Customer >, CustID);

SqlCommand cmd = new SqlCommand (sSQL, conn2)

Объём кода при этом значительно сокращается — необходимость описывать параметр , его тип и значение просто отпадает.

2 9 . Приступая к созданию своего первого более-менее сложного проекта , не забудьте создать класс для размещения в нём всевозможных мелких вспомогательных утилит. Фактически , наличие такого класса (как правило с именем Utils ), стало стандартом для проектирования информационных систем на С #. Получиться что-то вроде аналог ящика для инструментов , из которого вы сможете время от времени доставать нужное (по контексту ситуации) приспособление.

30 . Создание глобальных переменных , видимых из любой части программы , является одним из стандартных положений для разработчика любого уровня . Чаще всего , такая необходимость связана с использованием каких-то глобальных настроек программы. Одним из решений этой задачи является использование настроек — пространство имён My. Setting . Тогда достаточно будет написать , ну скажем в классе Utils ( см. Совет 29 ) , простой метод для ‘ выдёргивания ‘ значения этой настройки , что-то вроде этого (в приведённом ниже примере , если уж рассматривать совсем конкретный случай , просто взят год , принятый по умолчанию) :

public static int GetGodSetting

return ( int .Parse)(My.Settings. Default .god);

В любом месте программы для загрузки года , принятого в настройках по умолчанию , можно использовать такое простое обращение :

int God = Utils .GetGodSetting;

31 . При использовании сложных классических WinForms, старайтесь не перегружать код формы. Например , если на форме есть много кнопок , нажатие которых надо обрабатывать , вместо такого кода (особенно если он забойный) . :

public void Btn1_Click(System. Object sender, System. EventArgs e)

// Здесь что-то обрабатываем при нажатии на кнопку Btn1

public void Btn 2 _Click(System. Object sender, System. EventArgs e)

// Здесь что-то обрабатываем при нажатии на кнопку Btn 2

public void BtnN_Click(System. Object sender, System. EventArgs e)

// Здесь что-то обрабатываем при нажатии на кнопку BtnN

. можно создать класс ну скажем clsClickBtn , в который вынести все методы обработки при нажатии на кнопку , а в конструкторе формы разместить сл. код :

Btn1.Click += new EventHandler ( clsClickBtn .Btn1_Click);

Btn2.Click += new EventHandler ( clsClickBtn .Btn2_Click);

BtnN.Click += new EventHandler ( clsClickBtn .BtnN_Click);

Код формы в этом случае может сильно ‘ похудеть ‘ .

04. 12 .2013 , г. Юрьевец

32 . Ещё один подход к обозначенной в п. 31 проблеме может быть следующий.

Сначала создаём структуру ну допустим для обработки нажатий на гиперссылку LinkLabel :

public LinkLabel l;

public LinkLabelLinkClickedEventHandler h;

public struLL( LinkLabel _l, LinkLabelLinkClickedEventHandler _h)

Далее создаём список из обозначенной выше структуры , что-то вроде такого :

private List struLL > GetLLList

List struLL > opList = new List struLL >();

opList.Add( new struLL (lL _ A, clsLLblClick .MethodA));

opList.Add( new struLL (lL _ B, clsLLblClick .MethodB));

opList.Add( new struLL (lL _ Z, clsLLblClick .MethodZ));

Для инициализации методов обработки при нажатии на гиперссылки (в случае нашего примера) осталось только в конструкторе формы прокрутить такой цикл :

foreach ( struLL ll in GetLLList)

3 3 . Каким образом можно проитерировать управляющие элементы (контролы в просторечии) на форме ? Один из подходов описан в Совете 26 . Но существует ещё одно решение , пожалуй даже более изящное и простое. Заключается оно в том , что нужные контролы просто помещаем на форме в какой-либо контейнер , типа Panel . В этом случае в конструктор формы помещаем такой простой код (как пример для Кнопок — объект Button ) для обработки нажатий :

// Цикл по кнопкам в панели 1 .

foreach ( Button btn in panel 1 .Controls)

btn.Click += new EventHandler (btnClik);

34. При работе со справочниками часто требуется вернуть значение кода (ключа) по значению описания ключа. Конечно , можно для решения такой задачки создать структуру с двумя полями. Но гораздо проще воспользоваться одной из уже существующих коллекций — например словарем Dictionary . Тогда указанный подход можно продемонстрировать на сл. примере.

Создаем следующий метод :

public static int ReturnKodTown( string s)

Dictionary int, string > DicTowns = new Dictionary int, string >();

DicTowns.Add( 2 , » Санкт-Петербург » );

DicTowns.Add( 3 , » Казань » );

DicTowns.Add( 4 , » Новосибирск » );

DicTowns.Add( 5 , » Краснодар » );

return DicTowns.First(a => a.Value == s).Key;

Теперь узнать код города для нашего примера очень легко :

string gorod = » Новосибирск » ;

int kod = ReturnKodTown (gorod);

35. При использовании параметризованных SQL- запросов предпочтительнее пользоваться более современным методом . AddWithValue вместо .Add. Указывать тип поля при таком подходе не обязательно , нужно только указать параметр и его значение :

var myCMD = new SqlCommand (strInsSvod, GlobalVar.conn)

var pars = myCMD.Parameters;

// Используем метод AddWithValue

pars.AddWithValue( «@myPar» , myVal);

36. В развитии темы использования более рациональных подходов создания параметризованных запросов ( Совет 35 ). У коллекции параметров Parameters объекта Command есть ещё один полезный метод , позволяющий загрузить п a раметры в запрос массивом. Называется он . AddRange :

// Готовим массив параметров .

private static SqlParameters [] GetMyPars

new SqlParameter ( «@par2» , myVal2)),

new SqlParameter ( «@parN» , myValN))

// Использование метода . AddRange

using ( var cmd = new SqlCommand (s, GlobalVar.conn))

var pc = cmd.Parameters;

3 7 . При инициализации коллекций типа List вместо такого кода :

List string > MyList = new List string >();

MyList. Add( » один » ) ;

. можно использовать более короткую эквивалентную запись :

3 8 . При работе с коллекциями иногда хотелось бы не только проитерировать их в одном операторе , но и совершить какую-то обработку. В качестве примера , предположим , что есть массив :

. и для значений массива меньше или равно 5 , нужно умножить на 2 , а для более 5 умножить на 3.

Здесь на помощь может придти делегат Func и блочный лямбда-оператор. Что-то вроде этого ( понятное дело , блочный лямбда-оператор может быть много сложнее и состоять не из одной строки , как в случае нашего простенького примера) :

Func int , int , int > myFunc = (z, y) => <

return ( z y) ? 2 * z : 3 * z ;

Теперь , чтобы получить массив обработанных значений gruppa , можно написать такой простой код одной строчкой ( никакого foreach не нужно ! ) :

var gruppa = myInt.Select(a => myFunc(a, 5)).ToArray();

10 .01. 2015 , г. Обнинск

40. Назначить свой обработчик событий, скажем, для ввода данных в TextBox можно еще и с использование лямбда-оператора сл. образом ( м етод MyObrabKeyPress ) :

textBox1.KeyPress += (o, e) => MyObrabKeyPress( o, e);

Тогда , даже можно создать свой метод для обработки нажатий в нескольких контролах , что-то вроде такого :

textBox1.KeyPress += (o, e) => MyObrabKeyPress( o, e);

textBox2.KeyPress += (o, e) => MyObrabKeyPress( o, e);

textBox3.KeyPress += (o, e) => MyObrabKeyPress( o, e);

textBoxN.KeyPress += (o, e) => MyObrabKeyPress( o, e);

Затем , такой метод лучше всего поместить в конструктор формы , на которой расположены наши контролы ( TextBox’ ы для случая нашего примера) :

41. Тем , кто создает приложения для работы с базами данных, случается иметь дело с весьма ‘забойными’ SQL-запросами, которые могут занять десятки строчек кода. Но хранить такие запросы в тексте программы, несмотря на определенное удобство для разработчика (код запроса виден прямо в теле программы) не всегда изящно по причине необходимости ‘ сцепки ‘ строчек в запросе. И здесь возможно два варианта решения задачи хранения ‘ тяжелых ‘ запросов. Первый заключается в перемещении запроса непосредственно в базу данных в виде хранимой процедуры ( Store Procedure) . Второй путь связан с перемещением скрипта в строковую переменную в Настройки ( Setting, см. п.30 )

42. В продолжении темы п.41 . В код программы на C# ‘запилить’ длинный SQL-запрос можно используя символ литерала ‘@’. В этом случае отпадает необходимость в конкатенации строк. Выглядит такая конструкция может приблизительно сл. образом :

string mySql = @»Первая длинная строка запроса

Вторая ну очень длинная строка запроса

Третья длинная строка запроса

Последня я строка ну очень длинного запроса» ;

Опубликовать проект Фриланс работа › C# в России 26 фильтр активен

Требуется .Net C#|WPF программист для удалённой работы. Необходимые навыки: — Знания ООП, шаблонов проектирования. — Уверенное знание .Net/WPF, C# — Опыт разработки БД, MsSql, Postgres — Системы контроля версий, Git. — Работа с багтрекером. — Ответственность.

Нужно сделать лабораторную работу 8. Выбор стратегии ценообразования в Visual Studio (стр 108 в учебнике) Есть готовый пример по варианту 6.»Выбор стратегии производства»

C# , C/C++, Прикладное программирование

Нужен человек, который умеет писать сценарии в Elma bpm и в целом умеет создавать бизнес процессы через нотации. Компания ищет исполнителя для создание БП в системе ELMA, необходимые компетенции Участие в формировании ТЗ, Консультации заказчика (сотрудники), Выбор.

Требования к кандидату по технологическому стеку: • Обязательно: .Net Core (2.1+), Entity Framework Core, JavaScript, React, HTML, CSS • Желательно: TypeScript, Redux, Microsoft UI Fabric, MS SQL Server, SharePoint 2020 SPFx, Git По задачам: Участие в.

Есть бот для телеграмма написанный на с#, управление в виде программы на под ос виндовс, нужно чтобы она запустилась на linux(debain) Через вайн и моно запустить программу не удалось, нужен человек который поможет это реализовать, если это реально

C# , Прикладное программирование, Linux/Unix

На входе набор треугольников (задан массивом, каждый треугольник описывается тремя вершинами). В каждой вершине известно значение функции. Необходимо на сторонах проверить соответствие точек и если есть совпадения( равные значения функции в точках ), то эти точки выписать в.

Цукерберг рекомендует:  Горизонтально центрированное меню с использованием только CSS

Необходимо сделать программу для авто ставки в БК фонбет.Данные будут браться с сайта.Желательно чтобы исполнитель был близко знаком с тематикой ставок, имел опыт написание данных программ.1.Бот должен отбирать ставки по кефу(настраиваемое).2.Ставить определенную сумму на.

C# , Прикладное программирование

Добрый день ! Ищем человека который сделать AutoUpdater для программы. На хостинге/на диске будут лежать файлы которые необходимо будет отзеркалить для пользовательских пк. Размер файлов в сумме 9-11 гигабайт ! Особенности Апдейтера: — должен проверять файлы быстро — должен.

Нужна доработка программы для получения данных от API датафида в режиме реального времени , расчет показателей по заданным формулам и отображение результата в графическом виде. Есть исходный код. Срок две-три недели

На диске есть папка в которой около 2000 папок в которых также есть подпапки и разные файлы — текстовые, изображения, видео. Нужно написать программу которая найдет только файлы jpeg, tif, png — переместит их все в одну папку и переименует в название_папки_1_1.jpeg.

C# , C/C++, Delphi/Object Pascal

Требуется Asp.Net C# программист для удалённой работы. Необходимые навыки: — Знания ООП, шаблонов проектирования. — Уверенное знание Asp.Net/MVC/C#, Asp.Net Core — Разработка на Backend с применением TDD — Возможность работать как над веб так и над C# проектами (разработка.

C# , Microsoft .NET, Веб-программирование

Нужна десктоп программа с базовым функционалом визуализации данных: т.е. построение графиков по ценам OHLC в виде баров, линий, свечей, таймфреймы для графиков (10сек, 1м, 5м и т.п.), гистограммы объема, линия с указанием времени и т.д. Несколько простеньких индикаторов.

C# , Прикладное программирование, Обработка данных

Нужен программист на юнити который может пересобрать билд апк, залить его на маркет, правлиьно настроить маркет сейчас у нас на плеймаркетах гугл а айос уже наши приложения есть, но их половину удалили .нужно переобпубликовать Оплата сдельная, вовремя на карту, работа.

Нужен програмист работавший с букмекерскими ботами на C#: технологии dotnetbrowser, puppeteer, selenium не желательно, но можно обсудить. задача делать ботов которые коннектся к букмекерам по websoket получают данные с сервера и пытаются ставить ставки, вся логика подготовки.

Краткий обзор языка C# A Tour of the C# Language

C# (произносится как «си шарп») — простой, современный объектно-ориентированный и типобезопасный язык программирования. C# (pronounced «See Sharp») is a simple, modern, object-oriented, and type-safe programming language. C# относится к широко известному семейству языков C, и покажется хорошо знакомым любому, кто работал с C, C++, Java или JavaScript. C# has its roots in the C family of languages and will be immediately familiar to C, C++, Java, and JavaScript programmers. Здесь представлен обзор основных компонентов языка. This tour provides an overview of the major components of the language. Если вы хотите изучить язык с помощью интерактивных примеров, рекомендуем поработать с нашими вводными руководствами по C# . If you want to explore the language through interactive examples, try our introduction to C# tutorials.

C# является объектно-ориентированным языком, но поддерживает также и компонентно-ориентированное программирование. C# is an object-oriented language, but C# further includes support for component-oriented programming. Разработка современных приложений все больше тяготеет к созданию программных компонентов в форме автономных и самоописательных пакетов, реализующих отдельные функциональные возможности. Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. Важная особенность таких компонентов — это модель программирования на основе свойств, методов и событий. Каждый компонент имеет атрибуты, предоставляющие декларативные сведения о компоненте, а также встроенные элементы документации. Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C# предоставляет языковые конструкции, непосредственно поддерживающие такую концепцию работы. Благодаря этому C# отлично подходит для создания и применения программных компонентов. C# provides language constructs to support directly these concepts, making C# a very natural language in which to create and use software components.

Вот лишь несколько функций языка C#, обеспечивающих надежность и устойчивость приложений: сборка мусора автоматически освобождает память, занятую уничтоженными и неиспользуемыми объектами; обработка исключений предоставляет структурированный и расширяемый способ выявлять и обрабатывать ошибки; строгая типизация языка не позволяет обращаться к неинициализированным переменным, выходить за пределы индексируемых массивов или выполнять неконтролируемое приведение типов. Several C# features aid in the construction of robust and durable applications: Garbage collection automatically reclaims memory occupied by unreachable unused objects; exception handling provides a structured and extensible approach to error detection and recovery; and the type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

В C# существует единая система типов. C# has a unified type system. Все типы C#, включая типы-примитивы, такие как int и double , наследуют от одного корневого типа object . All C# types, including primitive types such as int and double , inherit from a single root object type. Таким образом, все типы используют общий набор операций, и значения любого типа можно хранить, передавать и обрабатывать схожим образом. Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. Кроме того, C# поддерживает пользовательские ссылочные типы и типы значений, позволяя как динамически выделять память для объектов, так и хранить упрощенные структуры в стеке. Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

Чтобы обеспечить совместимость программ и библиотек C# при дальнейшем развитии, при разработке C# много внимания было уделено управлению версиями. To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#’s design. Многие языки программирования обходят вниманием этот вопрос, и в результате программы на этих языках ломаются чаще, чем хотелось бы, при выходе новых версий зависимых библиотек. Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. Вопросы управления версиями существенно повлияли на такие аспекты разработки C#, как раздельные модификаторы virtual и override , правила разрешения перегрузки методов и поддержка явного объявления членов интерфейса. Aspects of C#’s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

Здравствуй, мир Hello world

Для первого знакомства с языком программирования традиционно используется программа «Hello, World». The «Hello, World» program is traditionally used to introduce a programming language. Вот ее пример на C#: Here it is in C#:

Файлы исходного кода C# обычно имеют расширение .cs . C# source files typically have the file extension .cs . Если код нашей программы Hello, World хранится в файле hello.cs, для ее компиляции выполните такую команду из командной строки: Assuming that the «Hello, World» program is stored in the file hello.cs, the program might be compiled using the command line:

В результате вы получите исполняемую сборку с именем hello.exe. which produces an executable assembly named hello.exe. Это приложение при запуске выводит следующий результат: The output produced by this application when it is run is:

Команда csc выполняет компиляцию на полной версии платформы, и она может существовать не на всех платформах. The csc command compiles for the full framework, and may not be available on all platforms.

Программа «Hello, World» начинается с директивы using , которая ссылается на пространство имен System . The «Hello, World» program starts with a using directive that references the System namespace. Пространства имен позволяют иерархически упорядочивать программы и библиотеки C#. Namespaces provide a hierarchical means of organizing C# programs and libraries. Пространства имен содержат типы и другие пространства имен. Например, пространство имен System содержит несколько типов (в том числе используемый в нашей программе класс Console ) и несколько других пространств имен, таких как IO и Collections . Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections . Директива using , которая ссылается на пространство имен, позволяет использовать типы из этого пространства имен без указания полного имени. A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Благодаря директиве using в коде программы можно использовать сокращенное имя Console.WriteLine вместо полного варианта System.Console.WriteLine . Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine .

Класс Hello , объявленный в программе «Hello, World», имеет только один член — это метод с именем Main . The Hello class declared by the «Hello, World» program has a single member, the method named Main . Метод Main объявлен с модификатором static. The Main method is declared with the static modifier. Методы экземпляра могут ссылаться на конкретный экземпляр объекта, используя ключевое слово this , а статические методы работают без ссылки на конкретный объект. While instance methods can reference a particular enclosing object instance using the keyword this , static methods operate without reference to a particular object. По стандартному соглашению точкой входа программы является статический метод с именем Main . By convention, a static method named Main serves as the entry point of a program.

Выходные данные программы создаются в методе WriteLine класса Console из пространства имен System . The output of the program is produced by the WriteLine method of the Console class in the System namespace. Этот класс предоставляется библиотеками стандартных классов, ссылки на которые компилятор по умолчанию добавляет автоматически. This class is provided by the standard class libraries, which, by default, are automatically referenced by the compiler.

Есть еще очень много важной информации о языке C#. There’s a lot more to learn about C#. В следующих статьях вы найдете сведения об отдельных элементах C#. The following topics provide an overview of the elements of the C# language. Эти краткие обзоры содержат базовые сведения обо всех элементах языка и позволят вам лучше разобраться в том, как работает C#. These overviews will provide basic information about all elements of the language and give you the information necessary to dive deeper into elements of the C# language:

  • Структура программы Program Structure
    • Организационная структура C# основывается на таких понятиях, как программы, пространства имен, типы, члены и сборки. Learn the key organizational concepts in the C# language: programs, namespaces, types, members, and assemblies.
  • Типы и переменные Types and Variables
    • Получите дополнительные сведения о типах значений, ссылочных типах и переменных в языке C#. Learn about value types, reference types, and variables in the C# language.
  • Выражения Expressions
    • Выражения создаются из операндов и операторов. Expressions are constructed from operands and operators. Выражения возвращают значения. Expressions produce a value.
  • Операторы Statements
    • Используйте инструкции для описания действий, выполняемых программой. You use statements to express the actions of a program.
  • Классы и объекты Classes and objects
    • Классы являются самым важным типом в языке C#. Classes are the most fundamental of C#’s types. Объекты представляют собой экземпляры классов. Objects are instances of a class. Классы создаются описанием их членов, которые также описаны в этой статье. Classes are built using members, which are also covered in this topic.
  • Структуры Structs
    • Структуры — это сущности для хранения данных. От классов они отличаются в первую очередь тем, что являются типами значений. Structs are data structures that, unlike classes, are value types.
  • Массивы Arrays
    • Массив — это структура данных, содержащая несколько переменных, доступ к которым осуществляется по вычисляемым индексам. An array is a data structure that contains a number of variables that are accessed through computed indices.
  • Интерфейсы Interfaces
    • Интерфейс определяет контракт, который может быть реализован классами и структурами. An interface defines a contract that can be implemented by classes and structs. Интерфейс может содержать методы, свойства, события и индексаторы. An interface can contain methods, properties, events, and indexers. Интерфейс не предоставляет реализацию членов, которые в нем определены. Он лишь перечисляет члены, которые должны быть определены в классах или структурах, реализующих этот интерфейс. An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.
  • Перечисления Enums
    • Тип enum представляет собой тип значения с набором именованных констант. An enum type is a distinct value type with a set of named constants.
  • Делегаты Delegates
    • Тип delegate представляет ссылки на методы с конкретным списком параметров и типом возвращаемого значения. A delegate type represents references to methods with a particular parameter list and return type. Делегаты позволяют использовать методы как сущности, сохраняя их в переменные и передавая в качестве параметров. Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Принцип работы делегатов близок к указателям функций из некоторых языков, но в отличие от указателей функций делегаты являются объектно-ориентированными и строго типизированными. Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.
  • Атрибуты Attributes
    • Атрибуты позволяют программам указывать дополнительные описательные данные о типах, членах и других сущностях. Attributes enable programs to specify additional declarative information about types, members, and other entities.

Курсовой на C# — работа с БД, отчетами, диаграммами

Автор: EJim · Опубликовано 22.12.2020 · Обновлено 11.11.2020

В начале 2020 года делал несколько лаб и пару курсовых на C#, в которых нужно было написать достаточно простую программу, работающую с базой данных. Программа хранит в базе информацию по заданной предметной области, выполняет запросы, строит отчеты, диаграммы.

На неделе нужно было сделать два других варианта курсовых. Поэтому решил описать процесс создания программы, чтобы и следующие работы выполнить быстрее, и описать алгоритм и нюансы работы с базой MS Access на C#. Может быть этот материал будет полезен и Вам. Работы делал в MS Visual Studio 2010, т.к. в наших ВУЗах свежий актуальный софт редкость (да и у студентов тоже). Возможно некоторых проблем не возникнет в более новых версиях студии.

Так выглядит общее задание на разработку программы:

Задание

Функции программы:
— вывод меню функций, выполняемых программой,
— ввод, просмотр, редактирование данных в базе данных (БД), содержащей не менее двух взаимосвязанных таблиц,
— вычисление значений полей в запросах,
— дополнение БД, удаление данных из БД,
— отбор (фильтрация) данных по условию, задаваемому пользователем,
— сортировка данных не менее чем по двум полям,
— формирование не менее двух отчётов по данным из БД (с группировкой, вычисляемыми полями и вычислением итоговых данных), которые могут быть выведены на принтер,
— построение на основе информации из БД не менее двух графиков (гистограммы, полигона или круговой диаграммы), характеризующих заданную предметную область,
— вывод формы со сведениями о программе (назначение, разработчик).

И конкретное задание первого варианта:

Структура данных 1.
Абитуриенты по факультетам и специальностям
Фамилия | Экзаменационные оценки (Математика | Физика | Сочинение) | Сумма баллов
Специальности
Код специальности | Наименование | Факультет
Примечание: выполнить сортировку по убыванию суммы баллов с группировкой по факультетам и специальностям, вычислить количество абитуриентов по факультетам, специальностям, по вузу.

Варианты выбора пользовательских функций: Кнопки
Вариант диаграммы: Столбиковая

Полное задание на курсовой со всеми вариантами заданий: PPP_KP_2013.

Выполнение

По началу я делал все последовательно — создавал проект в студии, накидывал интерфейс, делал таблицы в Access, реализовывал работу с ними в приложении, затем переходил к созданию запросов в Access и работе с ними в приложении, продумывал какие отчеты, какие диаграммы строить на основе имеющихся данных. Так было проще втянуться в процесс и вспомнить некоторые подзабытые моменты работы со средой и курсовым. Но конечно правильнее сначала проанализировать вариант задания, после чего создать и связать таблицы, продумать какие запросы, отчеты и диаграммы построить, заполнить таблицы данными. И только после этого приступать к написанию программы.

По ТЗ нужно не менее двух таблиц, так что у меня для сделанных вариантов получалось по три-четрые таблицы — в зависимости от того, какие сущности можно выделить на основе таблиц задания.

Не смотря на то, что в MS Access можно давать имена объектам с пробелом. Делать этого не стоит, т.к. когда я дошел до создания отчетов с помощью компонента ReportViewer, возникли проблемы с полями в названии которых был пробел — имя поля обрезалось до первого слова, и поэтому не смог их использовать в отчетах. Возможно, что проблема есть только в Visual Studio 2010, и в более свежих версиях исправлена — не проверял. Когда с ней столкнулся, решения не нашел, и переделывал все под имена с символом подчеркивания вместо пробела.

Таблицы и формы

Итак проанализировал задание, создал таблицы и связи, заполнил их данными, создал запросы в MS Access. Для первого варианта у меня вышла следующая схема:

Создал интерфейс главной формы в соответствии с вариантом задания (могут быть кнопки, метки, меню, переключатели, вкладки), и остальные 7 форм. Подробно описывать все шаги нет смысла, т.к. код отображения форм, можно взять из любого готового проекта. А вот некоторые действия в визуальном редакторе Visual Studio стоит запомнить.

После добавления первого компонента DataGridView на форму, можно добавить источник данных проекта. В окне ниже обычно отвечал «Да», хотя это не принципиально.

Просто в этом случае нужно помнить, что файл базы с актуальными данными постоянно копируется в каталог с exe-файлом из каталога проекта.

Для выполнения задания по сортировке и фильтрации данных интерфейс сделал со вкладками, где на одной вкладке полноценно реализована сортировка и фильтрация данных, на другой связанные таблицы.

Для расположения элемента TabControl во всю ширину/высоту родительского окна необходимо задать свойство Dock.

Согласно моей схеме базы данных между Факультетами и Специальностями связь один-ко-многим (не наоборот!) поэтому сначала выбрал отображение информации о факультетах:

Затем сделал связь факультета со специальностями:
Связь один-ко-многим между Специальностями и Абитуриентами реализовал в приложении:

С помощью пункта «Правка столбцов» прячем ненужные столбцы, задаем ширину и меняем заголовки видимых столбцов, добавляем нужные столбцы, указываем формат вывода данных с помощью свойства DefaultCellStyle (денежный, числовой, даты).

В данном варианте на второй вкладке решил отображать данные об абитуриентах, поскольку они наиболее интересны. Но видимо из-за связи на первой вкладке Абитуриентов со Специальностями , поле Код таблицы Абитуриенты не получилось скрыть — оно просто не реагировало на задание свойства Visible в false. Поматерился на эту фичу и задал минимально возможную ширину в 2px для этого поля.

Далее мне понадобилось вычисляемое поле «Сумма баллов». Его добавил непосредственно в наборе данных DataSet. Для таблицы Абитуриенты добавил новый столбец и определил его свойство Expression: Математика + Физика + Сочинение

Чтобы отобразить в Абитуриентах вместо id значение поля из связанной таблицы Специальности нужно добавить «Непривязанный столбец» в интерфейсе правки столбцов элемента DataGridView, заодно выбрав его тип ComboBox:

Чтобы поле выглядело как обычное текстовое нужно поменять DisplayStyle на Nothing. В списке выбора для этого поля нужно отобразить все данные из таблицы Специальности, поэтому в DataSourse выбираем её непосредственно из набора данных DataSet. Далее настраиваем связь данных: в DisplayMember выбираем поле с названиями для отображения (Специальности.Наименование), в ValueMember — поле с id (Специальности.Код), в DataPropertyName значение id соответствующее ValueMember (Абитуриенты.Специальность).

Цукерберг рекомендует:  Стили для текстов и ховер-эффекты

Сортировка и фильтрация полностью делаются с помощью кода и копируются из моих готовых проектов.

Чтобы связанные таблицы корректно работали на событие CellEndEdit для всех DataGridView нужно повесить код аналогичный этому:

УЧИСЬ ДОМА!

На этой странице собраны материалы для обучению одному из самых мощных языков программирования C#

Установка

Книга советов и рекомендаций. Для тех, кто уже познакомился с программированием на C#

Ссылки. Основы

  • Ссылка на мой плейлист с уроками на YouTube
  • Ссылка на курс «Изучаем язык программирования C#» в обучающей системе Moode (используйте гостевой доступ)
  • Лекции «Программирование на языке С#: разработка консольных приложений»

Ссылки. Продвинутый уровень

C# — Подборщик на c#

Данная статья первая из цикла «Парсим сайты на C#». В ней мы научимся непосредственно подключаться к выбранному серверу, скачивать страничку, разбирать её исходный код, а также выводить на экран первоначальные результаты и записывать их в файл. В следующих статьях программа будет улучшаться и обрастать другими функциями. В итоге попробуем сделать самое настоящее приложение — парсер для сайтов самостоятельно.

Итак, начнем мы с того, что научимся получать страничку. В данном случае пациентом выступает рейтинг топ майл ру, конкретно страница с адресом «top.mail.ru/Rating/Computers-Programming/Today/Visitors/4.html» — именно в этом ареале в настоящий момент обитает мой блог. Эту страницу мы скачиваем, ищем на ней адрес «upread.ru» (парсим) и выводим место, на котором данный сайт. Одновременно, с интервалом в 10 минут пишем этот результат в файл. На выходе будет примерно такая картинка.

А вот и сам код программы:

Несколько комментариев по коду выше. В строках 30-32 создаем WebClient; далее открываем поток для чтения данных. Обращаем внимание на строку 34 — здесь задается кодировка скачиваемой страницы. В 35-40 строках в цикле считываем построчно документ в массив. Далее, не забыв закрыть соединение, проходим весь массив и ищем соответствие (вхождение подстроки в строку) с помощью специального оператора си шарп — IndexOf(). В найденной элементе массива убираем пробелы (строка номер 49) и вырезаем номер позиции. Далее в строке 51 конвертируем результат в Int — это нам пока не надо, но далее в развитии функционала программы понадобится.

Строки 54-57 записывают номер позиции и время в файл, а строках 62-65 создаем и сразу запускаем (после загрузки формы) таймер с интервалом в 10 минут. Вот так мы создали простейший парсер страниц на си шарп. Продолжение следует.

Главное в .NET — Написание скриптов на C#

С выходом Visual Studio 2015 Update 1 (далее для краткости Update 1) появился новый C# REPL (read-evaluate-print-loop), доступный как новое интерактивное окно в Visual Studio 2015 или как новый интерфейс командной строки (command-line interface, CLI), названный CSI. В дополнение к существующему языку C# в командной строке Update 1 также вводит новый скриптовый язык C#, традиционно сохраняемый в CSX-файл.

Прежде чем погружаться в детали новой поддержки написания скриптов на C#, важно понимать целевые сценарии. Поддержка скриптов на C# — это средство для тестирования ваших фрагментов кода на C# и .NET, не прикладывая усилия к созданию множества проектов модульного тестирования или консольных проектов. Она предоставляет облегченный вариант для быстрого кодирования вызова LINQ-метода агрегации в командной строке, проверки .NET API для распаковки ZIP-файлов или вызова REST API для прояснения того, что он возвращает или как он работает. Вы получаете простые средства для исследования и понимания какого-либо API без издержек появления еще одного CSPROJ-файла в вашем каталоге %TEMP%.

Интерфейс командной строки C# REPL (CSI.EXE)

Как и при изучении самого C#, лучший способ начать освоение интерфейса C# (CSI) REPL — запустить его и приступить к выполнению команд. Для запуска интерфейса, введите команду csi.exe из командной строки Visual Studio 2015 или используйте полный путь C:\Program Files (x86)\MSBuild\14.0\bin\csi.exe. Отсюда начнется выполнение выражений C# по аналогии с тем, что показано на рис. 1.

Рис. 1. Пример CSI REPL

Первым делом отмечу очевидное — он похож на C#, хоть и на новый диалект C# (но без формальностей, которые ценятся в полностью производственной программе и не обязательных в сделанном на скорую руку прототипе). Поэтому, как и следовало ожидать, если вы хотите вызвать какой-нибудь статический метод, то можете написать полное имя метода и передать аргументы внутри скобок. Как и в C#, вы объявляете переменную, предваряя ее типом и (не обязательно) присваивая ей новое значение в момент объявления. И вновь, как и следовало ожидать, нормально работает любой допустимый синтаксис тела метода — блоки try/catch/finally, объявление переменных, лямбда-выражения и LINQ.

И даже в командной строке поддерживаются другие средства C# вроде строковых конструкций (чувствительность к регистру букв, строковые литералы и интерполяция строк). Поэтому, когда вы используете или выводите пути, для каждого обратного слеша нужно ставить escape-символ C# (\), как это делается двойными обратными слешами в пути запуска csi.exe. Интерполяция строк тоже работает, что демонстрирует пример строки «текущего каталога» на рис. 1.

Однако поддержка скриптов в C# позволяет делать гораздо больше, чем просто набирать выражения в командной строке. Вы можете объявлять собственные типы, встраивать метаданные типа через атрибуты и даже упрощать вывод, используя специфичные для скриптов на C# директивы. Рассмотрим пример с проверкой правописания на рис. 2.

Рис. 2. Скриптовый C#-класс Spell (Spell.csx)

По большей части это просто стандартное объявление C#-класса. Однако здесь есть несколько специфичных для скриптов на C# средств. Во-первых, директива #r служит для ссылки на внешнюю сборку. В данном случае это ссылка на Newtonsoft.Json.dll, которая помогает разбирать JSON-данные. Но заметьте, что эта директива предназначена для ссылок на файлы в файловой системе. Как таковая, она не требует лишних формальностей с escape-символами для обратных слешей.

Во-вторых, вы можете взять весь этот листинг и сохранить его как CSX-файл, а затем «импортировать» или «подставить» (inline) файл в окно C# REPL, используя #load Spell.csx. Директива #load позволяет включать дополнительные файлы скриптов так, будто все #load-файлы были включены в один и тот же «проект» или «компиляцию». Размещение кода в отдельном файле C#-скрипта обеспечивает своего рода рефакторинг файла и, что важнее, возможность хранить C#-скрипт.

Использование объявлений — еще одно языковое средство C#, включенное в скрипты C#; оно несколько раз используется в коде на рис. 2. Заметьте, что, как и в C#, область объявления using ограничена файлом. Поэтому, если вы вызвали #load Spell.csx из окна REPL, объявление using Newtonsoft.Json не сохранится за пределами Spell.csx. Иначе говоря, использование Newtonsoft.Json из Spell.csx не сохранилось бы в окне REPL без его повторного явного объявления в окне REPL (и наоборот). Также заметьте, что поддерживается и объявления using static из C# 6.0. Благодаря этому объявление using static System.Console исключает необходимость предварять любой из членов System.Console типом, разрешая выполнение таких REPL-команд, как WriteLine(«Hello! My name is Inigo Montoya»).

Другие конструкции, заслуживающие внимания в скриптах на C#, включают атрибуты, выражения using, объявление свойства и функции и поддержку async/await. Учитывая поддержку последнего функционала, await можно использовать даже в окне REPL:

Ниже дан ряд дополнительных замечаний по интерфейсу C# REPL.

  • Запустить csi.exe из Windows PowerShell Integrated Scripting Environment (ISE) нельзя, так как эта программа требует прямого консольного ввода, что не поддерживается имитируемыми консольными окнами Windows PowerShell ISE. (По этой причине подумайте о ее добавлении в список неподдерживаемых консольных приложений $psUnsupportedConsoleApplications.)
  • Команды exit или quit для выхода из CSI-программы нет. Вместо этого используйте Ctrl+C для завершения программы.
  • Журнал команд (command history) сохраняется между сеансами работы с csi.exe, запускаемыми из одного и того же сеанса cmd.exe или PowerShell.exe. Например, если вы запускаете csi.exe, вызываете Console.WriteLine(«HelloWorld»), используете Ctrl+C для выхода, а затем снова запускаете csi.exe, нажатие стрелки вверх покажет предыдущую команду: Console.WriteLine(«HelloWorld»). Выход из окна cmd.exe с последующим перезапуском очистит журнал команд.
  • Csi.exe поддерживает REPL-команду #help, которая дает вывод, показанный на рис. 3.
  • Csi.exe поддерживает ряд параметров в командной строке, как представлено на рис. 4.

Рис. 3. Вывод REPL-команды #help

Рис. 4. Параметры командной строки csi.exe

Для верстки: в этом листинге не обойтись без наезда на соседнюю колонку, иначе будет сильное искажение вывода

Как отмечалось, csi.exe позволяет указывать файл «профиля» по умолчанию, который настраивает ваше окно команд.

  • Чтобы очистить консоль CSI, вызовите Console.Clear. (Подумайте насчет директивы using static System.Console для добавления поддержки вызова просто Clear.)
  • Если вы вводите команду, занимающую несколько строк, и обнаруживаете ошибку на одной из предыдущих строк, то можете использовать Ctrl+Z с последующим нажатием Enter для отмены и возврата к пустой строке приглашения без выполнения (заметьте, что в консоли появится ^Z).

Окно C# Interactive в Visual Studio

Как упоминалось, в Update 1 появилось и новое окно C# Interactive (рис. 5). Это окно запускается через View | Other Windows | C# Interactive и открывается как дополнительное стыкуемое окно. Как и окно csi.exe, это окно C# REPL, но с несколькими дополнительными средствами. Прежде всего оно включает цветовое выделение синтаксиса кода и поддержку IntelliSense. Аналогично компиляция выполняется в реальном времени по мере того, как вы редактируете код, поэтому синтаксические ошибки и другие огрехи автоматически подчеркиваются волнистой красной линией.

Рис. 5. Объявление скриптовой функции C# вне класса, использующего окно C# Interactive в Visual Studio

Окно C# Interactive, конечно, сразу же ассоциируется с окнами Immediate и Command в Visual Studio. Хотя они перекрываются по своей функциональности (в конце концов, это REPL-окна, в которых вы выполняете .NET-выражения), они имеют существенно разное предназначение. Окно C# Immediate прямо связано с отладочным контекстом вашего приложения, тем самым позволяя вводить дополнительные выражения в контекст, изучать данные в сеансе отладки и даже манипулировать/обновлять данные и отладочный контекст. Аналогично окно Command предоставляет CLI для манипуляций над Visual Studio, включая выполнение различных меню, но не из самих меню, а из окна Command. (Например, выполнение команды View.C#Interactive открывает окно C# Interactive.) В противоположность этому окно C# Interactive позволяет выполнять C#, включая все средства, относящиеся к интерфейсу C# REPL, рассмотренному в предыдущем разделе. Однако окно C# Interactive не имеет доступа к отладочному контексту. Это полностью зависимый сеанс C# без описателей (handles) отладочного контекста или даже Visual Studio. Подобно csi.exe это среда, которая позволяет экспериментировать с фрагментами кода на C# и .NET для проверки вашего понимания без запуска еще одного консольного проекта или проекта модульного тестирования Visual Studio. Но вместо запуска в отдельной программе окно C# Interactive размещается в Visual Studio, где предположительно уже находится разработчик.

Ниже приведено несколько замечаний по окну C# Interactive.

  • Оно поддерживает ряд дополнительных REPL-команд, отсутствующих в csi.exe, в том числе:
    • #cls/#clear для очистки содержимого окна редактора;
    • #reset для восстановления среды выполнения до ее начального состояния с сохранением журнала команд.
  • Клавиатурные комбинации немного неожиданные, как показывает вывод #help в табл. 1.

Табл. 1. Комбинации клавиш, действующие в окне C# Interactive

Enter Если текущее выражение полное, оно оценивается. В ином случае вставляется новая строка
Ctrl+Enter Оценивается текущее выражение
Shift+Enter Вставка новой строки
Esc Очистка текущего выражения
Alt+стрелка вверх Замена текущего выражения предыдущим
Alt+стрелка вниз Замена текущего выражения последующим (если ранее был переход назад)
Ctrl+Alt+стрелка вверх Замена текущего выражения предыдущим, начинающимся с того же текста
Ctrl+Alt+стрелка вниз Замена текущего выражения последующим, начинающимся с того же текста (если ранее был переход назад)
Стрелка вверх В конце текущего выражения его замена предыдущим. В ином случае перемещение курсора на строку вверх
Стрелка вниз В конце текущего выражения его замена последующим (если ранее был переход назад). В ином случае перемещение курсора на строку вниз
Ctrl+K, Ctrl+Enter Вставка выделенного блока в конец интерактивного буфера; «каретка» остается в в конце ввода
Ctrl+E, Ctrl+Enter Вставка и выполнение выделенного блока до любого незавершенного ввода в интерактивном буфере
Ctrl+A При первом нажатии выделяет выражение, в котором находится курсор. При втором нажатии выделяет весь текст в окне

Важно отметить, что Alt+стрелка вверх/вниз — это комбинации клавиш для вызова журнала команд. Microsoft выбрала эти комбинации вместо более простых «стрелка вверх/вниз», поскольку хотела, чтобы окно Interactive работало так же, как и стандартное окно кода в Visual Studio.

  • Поскольку окно C# Interactive размещается в Visual Studio, в нет тех же возможностей передачи ссылок, использования директив или импорта через командную строку, как в случае csi.exe. Вместо этого окно C# Interactive загружает свой контекст выполнения по умолчанию из C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\CSharpInteractive.rsp, который идентифицирует сборки для ссылок по умолчанию:

Более того, файл CSharpInteractive.rsp ссылается на файл C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\SeedUsings.csx по умолчанию:

Комбинация этих двух файлов является причиной того, что вы используете Console.WriteLine и Environment.CurrentDirectory вместо полных System.Console.WriteLine и System.Environment.CurrentDirectory соответственно. Кроме того, ссылки на сборки, такие как Microsoft.CSharp, позволяют использовать языковые средства вроде dynamic безо всяких дополнительных усилий. (Модификация этих файлов дает возможность изменять ваш «профиль» или «предпочтения» так, чтобы эти изменения сохранялись между сеансами.)

Подробнее о синтаксисе скриптов на C#

Один из моментов, которые следует учитывать в отношении синтаксиса C#-скриптов, заключается в том, что большая часть формальностей, важных в стандартном C#, становится соответственно не обязательной в C#-скрипте. Например, такие вещи, как тела методов не обязаны находиться в какой-либо функции, а функции C#-скрипта можно объявлять вне границ какого-либо класса. Скажем, вы могли бы определить NuGet-функцию Install, которая появляется непосредственно в REPL-окне, как показано на рис. 5. Кроме того, возможно, несколько неожиданно, C#-скрипты не поддерживают объявления пространств имен. Например, вы не можете обернуть класс Spell в пространство имен Grammar: namespace Grammar < class Spell <>>.

Важно отметить, что вы можете объявлять одну и ту же конструкцию (переменную, класс, функцию и т. д.) снова и снова. Последнее объявление следует любому более раннему объявлению.

Другой важный момент, о котором нужно знать, — поведение точки с запятой, завершающей команду. Операторы (например, присваивания переменных) требуют точки с запятой. Без нее REPL-окно будет по-прежнему предлагать дальнейший ввод (через точку), пока не будет введена точка с запятой. С другой стороны, выражения будут выполняться без точки с запятой. Следовательно, System.Diagnostics.Process.Start(«notepad») запустит Notepad даже без концевой точки с запятой. Более того, поскольку вызов метода Start возвращает процесс, в командной строке появится строковый вывод выражения: [System.Diagnostics.Process (Notepad)]. Но закрытие выражения точкой с запятой скроет этот вывод. Поэтому вызов Start с концевой точкой с запятой не даст никакого вывода, хотя Notepad все равно будет запущен. Конечно, Console.WriteLine(«It would take a miracle.»); будет по-прежнему выводить текст, даже без точки с запятой, поскольку вывод отображает сам метод.

Выражения (expressions) и операторы (statements) иногда имеют тонкие отличия. Например, оператор string text = «There’s a shortage of perfect b….»; не даст никакого вывода, а text=»Stop that rhyming and I mean it» вернет присвоенную строку (поскольку присваивание возвращает присвоенное значение и в конце нет точки с запятой, которая подавила бы вывод).

Директивы в C#-скриптах для ссылок на дополнительные сборки (#r) и импорт существующих C#-скриптов (#load) — великолепные новшества. К сожалению, на момент написания этой статьи NuGet-пакеты не поддерживались. Для ссылки на файл из NuGet требуется установить этот пакет в каталог, а затем сослаться на конкретную DLL через директиву #r. (В Microsoft меня уверили, что вскоре необходимая поддержка появится.)

Заметьте, что на этот раз директивы ссылаются на конкретные файлы. Указать в директиве, например, какую-то переменную нельзя. Хотя этого и следовало ожидать, это исключает возможность динамической загрузки сборки. Скажем, вы могли бы динамически запускать nuget.exe install для извлечения сборки (вновь см. рис. 5). Однако тогда ваш CSX-файл было бы нельзя динамически связать с извлеченным NuGet-пакетом, так как нет никакого способа динамически передавать путь сборки в директиву #r.

C# CLI

Должен признаться, что у меня двоякое отношение к Windows PowerShell. Мне нравится удобство работы с Microsoft .NET Framework в командной строке и возможность передачи .NET-объектов по конвейеру, а не традиционного текста, как это делается во многих других CLI. Когда дело доходит до языка C#, я становлюсь пристрастен: обожаю его элегантность и мощь. (До сих пор я остаюсь под впечатлением от языковых расширений, которые сделали возможной работу с LINQ.) Поэтому идея сочетания свободы действий в Windows PowerShell .NET с элегантностью языка C# наводила на мысль, что C# REPL может быть заменой Windows PowerShell. После запуска csi.exe я сразу же опробовал команды вроде cd, dir, ls, pwd, cls, alias и им подобные. Достаточно сказать, что я был разочарован, так как ни одна из них не работала. После раздумий и обсуждения с группой C# я осознал, что замена Windows PowerShell не была в числе задач, на которых группа сосредоточилась в версии 1. Более того, это .NET Framework, а значит, она поддерживает расширяемость добавлением ваших собственных функций для предыдущих команд и даже обновлением реализации C#-скрипта в Roslyn. Я немедленно приступил к определению функций для таких команд. Получившаяся в итоге библиотека в своем начальном виде доступна для скачивания на GitHub по ссылке github.com/CSScriptEx.

Для тех, кто ищет более функциональный C# CLI, который изначально поддерживает предыдущий список команд, присмотритесь к ScriptCS на scriptcs.net (или на GitHub по ссылке github.com/scriptcs). Он тоже использует Roslyn и включает поддержку псевдонимов, команд cd, clear, cwd, exit, help, install, reset, ссылок, пакетов скриптов, выражений using и var. Заметьте, что в случае ScriptCS префиксом команд сегодня является двоеточие (как в :reset), а не символ # (как в #reset). В качестве бонуса ScriptCS также добавляет поддержку CSX-файлов с цветовым выделением и IntelliSense в Visual Studio Code.

Заключение

По крайней мере пока целью интерфейса C# REPL не является замена Windows PowerShell или даже cmd.exe. Ожидание этого приведет к разочарованию. Вместо этого я предлагаю относиться к C#-скриптам и различным REPL CLI как к облегченным заменам Visual Studio | New Project: UnitTestProject105 или к аналогам на dotnetfiddle.net. Это способы, ориентированные на C# и .NET, должны углубить ваше понимание языка и .NET API. C# REPL предоставляет средства для кодирования коротких фрагментов или блоков программы, с которыми вы можете поэкспериментировать, пока они не будут готовы для вставки в более серьезные программы. Это позволяет вам писать более содержательные скрипты, чей синтаксис проверяется «на лету» в процессе написания кода (вылавливаются даже такие мелкие ошибки, как неправильный регистр букв), и вас не вынуждают запускать скрипт только для того, чтобы обнаружить, что вы где-то опечатались. Как только вы это поймете, поддержка скриптов на C# и ее интерактивные окна станут приятным инструментом, который вы искали с момента появления первой версии языка.

Как бы ни были интересны C# REPL и поддержка скриптов на C# сами по себе, считайте, что они также являются плацдармом инфраструктуры расширения для ваших приложений — а-ля Visual Basic for Applications (VBA). Благодаря интерактивному окну и поддержке скриптов на C# вы можете вообразить мир (не столь уж и несбыточный), в котором вновь можно добавлять в приложения «макросы», но уже относящиеся к .NET, — без изобретения собственного языка, средства синтаксического анализа и редактора.

Марк Михейлис (Mark Michaelis) — учредитель IntelliTect, где является главным техническим архитектором и тренером. Почти два десятилетия был Microsoft MVP и региональным директором Microsoft с 2007 года. Работал в нескольких группах рецензирования проектов программного обеспечения Microsoft, в том числе C#, Microsoft Azure, SharePoint и Visual Studio ALM. Выступает на конференциях разработчиков, автор множества книг, последняя из которых — «Essential C# 6.0 (5th Edition)» (itl.tc/EssentialCSharp). С ним можно связаться в Facebook (facebook.com/Mark.Michaelis), через его блог (IntelliTect.com/Mark), в Twitter (@markmichaelis) или по электронной почте mark@IntelliTect.com.

Выражаю благодарность за рецензирование статьи экспертам Microsoft Кевину Босту (Kevin Bost) и Кейси Олинхуту (Kasey Uhlenhuth).

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