Можете меня пинать и ругать сколько хотите за то, что я до мозга костей делфиец. Но я, честно, стараюсь стать хорошим. Тут в связи с производственной необходимостью пришлось осваивать C#. Вообще синтаксис у него хороший. Мне нравится. Порой можно больше, чем в Delphi. Но от его нелогичности я просто в шоке. Итак презентуем грабли, часть первая.
Пространство имен System.Configuration. Дабы предостеречь тех кто любит видеть только вершину айсберга сообщаю – Using System.Configuration было прописано. Требуется – обеспечить чтение настроек приложения. Имеется пример на MSDN в котором используется класс ConfigurationManager. Скопирован код из мсдн, попытка запустить – фиг. ConfigurationManager – неизвестный идентификатор в данном пространстве имен. Что за ерунда думаю я. Смотрю System.Configuration. Действительно, никакого ConfigurationManager там нет, есть ConfigurationSettings. Применяю его. Warning – данный класс используется только для обратной своместимости. Извольте обратиться к классу ConfigurationManager. Которого просто нет в данном просранстве имен.
Решение: Добавить в References Сборку System.Configuration.dll.
Причина: Привычка, что в Delphi если в uses прописал юнит, то все что в нем есть сразу доступно. Несмотря на то, что в Delphi тоже есть что-то наподобие сборок… Но там такого маразма нет, что если объявил пространство имен нужно еще добавлять к проекту ссылку на сборку. самое главное хоть бы подсказка была какая-то компилятором, что для того, чтобы данным пространством имен воспользоваться в ПОЛНОМ объеме нужно еще добавить ссылку на сборку. Кстати, во всех юнитах Делфи есть комментарии к функциям в сорсах и очень часто примеры использования. Жмешь на методе Ctrl+клик – и смотришь какие нам рекомендации дал сам разработчик по использованию его класса. В C# – ничего такого нет. Если бы не аналогичная проблема на одном американском форуме и мое умение общаться на английском- я бы врядли вообще додумался до этого.
Затраченное время: 4 часа
Поехали дальше.
Возможность работать с INI файлами отсутствует. Спасибо парни из Майкрософт, что за меня решили как лучше хранить настройки программы. Итак, дядя сэм предлагает нам несколько вариантов:
- Реестр
- Application Directory
- Config файлы – по сути 1 раздел в xml файле
Реестр мне не подходит, так как пользователь должен иметь аозможность изменить настройки программы вручную. Application Directory – не очень удобно, но возможно. Как всегда взял пример из MSDN запустил, не работает. На этот раз ни единой ошибки. Пример отрабатывает нормально, просто настройки которые я сохранил в файле так и не соизволили появиться. После копания в гугле, наткнуля на аналогичную проблему. Я так понял, что для консольных приложений такой вариант отсутствует. А почему тогда программа компилируется и выполняется? Спросите у тех, кто делал .NET3.5. И последний вариант – .config файлы. Чтение настроек из файлов происходит без проблем. Но вот с сохранением – опять жопа.
Код чтения настроек:
public
static string
GiveAppSettings(string
Key)
{
// Get the AppSettings collection.
NameValueCollection appSettings
= System.Configuration.ConfigurationManager.AppSettings;
return appSettings.Get(Key);
}
appSettigs имеет также метод Set, который меняет настройку в пределах приложения. Однако никакой связи с сохранением настройки в файл конфигурации я не увидел. Помимо класса ConfigurationManager есть еще и класс System.Configuration.Configuration. В котором после нехитрых манипуляций можно добавить настройку в файл методом Add. Однако, метод ее изменения найден мною не был. Что примечательно, в данном классе также есть подкласс AppSettings. Название такое же. Методы другие. Я бы руки оторвал программистам, которые делают такие классы. Разные, но с одинаковыми названиями. Позже на блоге одного американского разработчика было найдено описание этой проблемы. Действительно, файл конфигурации можно читать, добавлять туда значения. Но менять – нет. Маразм? Маразм! Конечно через жопу со стираением настроек можно. Но где хваленое удобство .NET? Чуть попозже выложу переведенную запись в блоге того программиста. Он написал собственный класс для работы с файлами конфигурации.
Шоу продолжатеся.
Затраченное время: 7 часов
Огромное спасибо! Мне не нравится делфи, но за «Добавить в References Сборку System.Configuration.dll» огромное спасибо!
Случайно зашел. Просто диву дался, не сдержался.
Krolm, вы бы для начала почитали какую-нибудь книжку по основам .net (даже не c#), там как правило расписано про сборки и про пространства имен и почему именно так сделано, а не иначе и приводится железобетонное логическое обоснование. И знакомство начинают с hello world в блокноте и консольным компилятором, на не с примеров msdn.
«Возможность работать с INI файлами отсутствует,» – ужос, они не читаются, не пишутся?
Вы смотрели класс String в c#? До дельфийского «швейцарского ножа» TStringList (который может парсит файлы типа name=value (в том числе и ini, и cfg и т.д. и т.п.) ему не хватает только добавки List и функционала работы с файлом. Это в свое время я реализовал ручками за 15 мин. А ведь еще есть System.Collections.Specialized.StringCollection
List , а если еще посмотреть, еще что найду.
.net – это разработка современная, в xml уже пора конфигурационные файлы хранить. по крайней мере для этого мелкомягкий все обеспечил.
В общем на мой взгляд 11 часов в пустую, за это время можно было вникнуть прежде всего в идеологию .net. Тогда две трети вашей статьи просто не состоялось бы.
mik, в университете год читался .net и читался при этом хорошо. До сих пор слайды тех лекций более полезны чем разный бред на форумах. 3 книги я тоже купил и прочитал.
Но такого рода «тонкости» меня напрягают. Я думаю вы не поняли смысл моей проблемы. Поясню.
System.Configuration является пространством, содержащим классы в нескольких сборках, в том числе в System.Configuration.dll. Так вот, набор стандартных сборок, который по умолчанию подключат студия уже позволяет появиться в IntelliSense классу System.Configuration, который объявлен как partial. Однако методов, указанных в msdn он содержать не будет, что ставит в тупик. И очень тяжело догадаться, что отсутствие нужных методов, при том что класс нормально объявляется и содержит какой-то функционал связан с тем, что другая половина функционала засунута в другую сборку. Правильнее было все организовать в одной сборке или указывать в справке, что для полного функционала подключайте такую-то сборку.