О сложностях программирования, или
C# нас не спасет?
Автор: Евгений Рыжков

Дата: 26.10.2010

Программирование это сложно. С этим никто, надеюсь, не спорит. Но вот тема новых языков
программирования, а точнее поиск "серебряной пули" всегда находит бурных отклик в умах
разработчиков программного обеспечения. Особенно "модной" является тема превосходства
одного языка программирования над другим. Ну, к примеру, что C# "круче", чем C++. И хотя holy
wars – это не та причина, по которой я пишу этот пост, тем не менее, что называется "наболело".
Ну не поможет C#/lisp/F#/Haskell/... написать изящное приложение, взаимодействующее с
внешним миром, и все тут. Вся изящность теряется, стоит захотеть написать что-то реальное, а не
пример "сам в себе".

В тексте несколько фрагментов на C#, взятые из модуля интеграции статического анализатора
кода PVS-Studio в популярную среду Microsoft Visual Studio. Этими фрагментами я хочу показать,
что писать, к примеру, на C# совсем не проще, чем на, C++.


Простой combobox
Этак, первый фрагмент кода – обработка выбора одной из трех строк в ОБЫЧНОМ combobox на
панели инструментов с картинки.




Рисунок 1 – Простой combobox на три строчки

И вот для обработки такой вот фитюльки требуется следующий код. К сожалению, пришлось
изменить форматирование и убрать комментарии. Так что прошу прощения за ужас.

private void OnMenuMyDropDownCombo(object sender, EventArgs e)

{

    if (e == EventArgs.Empty)

    {

        throw (new ArgumentException());
}



OleMenuCmdEventArgs eventArgs = e as OleMenuCmdEventArgs;



if (eventArgs != null)

{

    string newChoice = eventArgs.InValue as string;

    IntPtr vOut = eventArgs.OutValue;



    if (vOut != IntPtr.Zero && newChoice != null)

    {

        throw (new ArgumentException());

    }

    else if (vOut != IntPtr.Zero)

    {

        Marshal.GetNativeVariantForObject(

            this.currentDropDownComboChoice, vOut);

    }



    else if (newChoice != null)

    {

        bool validInput = false;

        int indexInput = -1;

        for (indexInput = 0;

              indexInput < dropDownComboChoices.Length;

              indexInput++)

        {

            if (String.Compare(

               dropDownComboChoices[indexInput], newChoice,

               true) == 0)
{

            validInput = true;

            break;

        }

    }



    if (validInput)

    {

        this.currentDropDownComboChoice =

             dropDownComboChoices[indexInput];

        if (currentDropDownComboChoice ==

             Resources.Viva64)

            UseViva64Analysis(null, null);

        else if (currentDropDownComboChoice ==

                     Resources.GeneralAnalysis)

            UseGeneralAnalysis(null, null);

        else if (currentDropDownComboChoice ==

                     Resources.VivaMP)

            UseVivaMPAnalysis(null, null);

        else

        {

            throw (new ArgumentException());

        }

    }

    else

    {

        throw (new ArgumentException());

    }

}

else
{

            throw (new ArgumentException());

        }

    }

    else

    {

        throw (new ArgumentException());

    }

}

Причем здесь IntPtr.Zero и Marshal.GetNativeVariantForObject()? Ну так надо... Простой combobox
обрабатывается совсем не просто.

Причем этого кода не достаточно. Есть еще рядом функция OnMenuMyDropDownComboGetList()
примерно такого же размера.

Здесь C# оказался ничем не лучше любого другого языка. Нет, конечно же, круто, что он
инкапсулировал от меня OLE, маршалинг. На Си все было бы намного печальней. Но вот только
как-то все равно все не то, как преподносится в книгах и эвангелистами. Простота-то где? Я всего
лишь хотел с выпадающим списком поработать.


Навигация по коду в Visual Studio
Когда в Visual Studio вы щелкаете по сообщению об ошибке, срабатывает примерно такой код для
открытия файла и перехода к строке с ошибкой.

public void OpenDocumentAndNavigateTo(string path, int line,

    int column)

{

            IVsUIShellOpenDocument openDoc =

                    Package.GetGlobalService(

                    typeof(IVsUIShellOpenDocument))

                    as IVsUIShellOpenDocument;

        if (openDoc == null)

             return;

        IVsWindowFrame frame;

        Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp;

        IVsUIHierarchy hier;
uint itemid;

  Guid logicalView = VSConstants.LOGVIEWID_Code;

  if (ErrorHandler.Failed(

      openDoc.OpenDocumentViaProject(path, ref logicalView,

        out sp, out hier, out itemid, out frame))

            || frame == null)

             return;

  object docData;

  frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData,

      out docData);



  VsTextBuffer buffer = docData as VsTextBuffer;

  if (buffer == null)

  {

        IVsTextBufferProvider bufferProvider =

             docData as IVsTextBufferProvider;

        if (bufferProvider != null)

        {

            IVsTextLines lines;

            ErrorHandler.ThrowOnFailure(

             bufferProvider.GetTextBuffer(out lines));

            buffer = lines as VsTextBuffer;

            if (buffer == null)

             return;

        }

  }

IVsTextManager mgr =

 Package.GetGlobalService(typeof(VsTextManagerClass))

 as IVsTextManager;

if (mgr == null)
return;

    mgr.NavigateToLineAndColumn(

      buffer, ref logicalView, line, column, line, column);

}

Ё-мое... Ужас. Набор магических заклинаний. Этот код, будучи написанным на C#, опять же ничем
не упростил жизнь своему разработчику. Кто скажет, что это будет лучше выглядеть на языке XYZ?
Язык здесь "перпендикулярен" к решаемой задаче и практически не оказывает влияния.


Работа с датой
Ну, уж работа с датами в C# должна быть точно на высоте! Ведь там столько разных удобных
форматов сделали. Думал я, до тех пор, пока из внешней программы не пришло время в формате
__time64_t, а в C# коде необходимо было использовать класс DateTime.

Конвертировать __time64_t в DataTime конечно не сложно, для этого всего лишь надо написать
функцию типа такой:

public static DateTime Time_T2DateTime(long time_t)

{

    //116444736000000000 - это 1600 год

    long win32FileTime = 10000000 * time_t + 116444736000000000;

    return DateTime.FromFileTime(win32FileTime);

}

И здесь C# оказался ничем не лучше... Возможно конечно я не нашел функцию конвертации. Ну,
неужели нельзя было у DateTime нужный конструктор сделать? Ну почему, как взаимодействие с
окружающей средой, так опять все по старинке "ручками" делать приходится?


Перебор всех проектов одного решения (solution)
Для некоторой задачи необходимо перебрать все проекты, которые есть в решении (Visual Studio
solution).

Вместо простого и элегантного foreach код выглядит так:

Solution2 solution = PVSStudio.DTE.Solution as Solution2;

SolutionBuild2 solutionBuild =

     (SolutionBuild2)solution.SolutionBuild;

SolutionContexts projectContexts =

     solutionBuild.ActiveConfiguration.SolutionContexts;
int prjCount = projectContexts.Count;

for (int i = 1; i <= prjCount; i++)

{

      SolutionContext projectContext = null;

      try

      {

            projectContext = projectContexts.Item(i);

      }

      catch (Exception)

      {

            // try/catch block is a workaround.

            // It's needed for correct working on solution

            // with unloaded projects.

            continue;

      }

...

Во-первых, оказывается, что foreach для этого класса недоступен. Но ладно, for-ом пользоваться
еще не разучились. Во-вторых, если обратиться к элементу, который в наборе есть, но у него "не
очень корректное" состояние – то летит исключение. В результате код заметно усложняется. А код
на C# опять ничем не отличается от кода на другом языке.


Выводы
Данным постом я хотел показать, что далеко не всегда код на C# (или другом языке) проще, чем
код на C/C++. И поэтому слепо верить в то, что "надо все переписать на C#" не нужно. Тем не
менее, я совершенно не считаю, что "C# - отстой", поскольку во многих местах он действительно
упрощает жизнь.

В чем причины того, что указанные в посте фрагменты кода выглядят также сложно, как и на C++?

    1. Взаимодействие с различными API. Например, как здесь было взаимодействие с Visual
       Studio API.
    2. Взаимодействие с программами на других языках. Например, тип __time64_t конечно же
       пришел от C++-приложения.
    3. Взаимодействие с операционной системой. Далеко не всегда удается состыковать
       красивый и правильный C#-код с реальностью в лице Windows.
    4. Несовершенство алгоритмов обработки данных. Если вы работаете со строками, то от "+1"
       в коде вы никуда не денетесь, на каком бы языке вы не писали.
Оправдания по использованному в примерах коду:

   1. Комментарии вырезаны, код сокращен до минимально необходимого в статье.
   2. Да, авторы кода не умеют писать на C#, но от этого C# не становится волшебнее.

More Related Content

PDF
Разница в подходах анализа кода компилятором и выделенным инструментом
PDF
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
PDF
PVS-Studio vs Chromium
PPTX
Евгений Зуев, С++ в России: Стандарт языка и его реализация
PPTX
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
PPTX
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
PPT
Юнит-тестирование и Google Mock. Влад Лосев, Google
PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Разница в подходах анализа кода компилятором и выделенным инструментом
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
PVS-Studio vs Chromium
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Юнит-тестирование и Google Mock. Влад Лосев, Google
Статический и динамический полиморфизм в C++, Дмитрий Леванов

What's hot (20)

PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
PPTX
C++ Core Guidelines
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PPTX
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
PDF
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
PPTX
Современный статический анализ кода: что умеет он, чего не умели линтеры
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PPT
C# 5.0. Взгляд в будущее
PDF
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
PDF
Павел Довгалюк, Обратная отладка
PDF
Акторы на C++: стоило ли оно того?
PPTX
Александр Фокин, Рефлексия в C++
PPTX
Tdd webpack + testem + mocha + chai
PDF
DI в C++ тонкости и нюансы
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
PDF
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
PDF
Антон Полухин, Немного о Boost
PPTX
Программирование на языке C Sharp (СИ решетка)
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
PDF
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Статический и динамический полиморфизм в C++, Дмитрий Леванов
C++ Core Guidelines
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Современный статический анализ кода: что умеет он, чего не умели линтеры
Для чего мы делали свой акторный фреймворк и что из этого вышло?
C# 5.0. Взгляд в будущее
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Павел Довгалюк, Обратная отладка
Акторы на C++: стоило ли оно того?
Александр Фокин, Рефлексия в C++
Tdd webpack + testem + mocha + chai
DI в C++ тонкости и нюансы
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
Антон Полухин, Немного о Boost
Программирование на языке C Sharp (СИ решетка)
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Ad

Viewers also liked (20)

PPTX
Особенности C#
PPTX
Увлекательный мир программирования.
PPTX
ООП. Рекомендуемые информационные ресурсы
PPTX
принципы ооп и программирование классов в C#
PPTX
Составные части объектного подхода
PPTX
Языки программирования
PPTX
Делегаты
PPTX
Chislovye tipy dannykh_i_ikh_ispolzovanie_v_vba
PPTX
PPTX
Интерфейсы
PPTX
Безопасное программирование на C#
PPTX
PPTX
DevPro-2014: Кроссплатформенное приложение за 15 минут или Беды и победы моби...
PPTX
язык программирования с#
PPTX
Luxoft async.net
PPTX
Наследование и полиморфизм
PPTX
Презентация курса "Основы программирования" на C#
Особенности C#
Увлекательный мир программирования.
ООП. Рекомендуемые информационные ресурсы
принципы ооп и программирование классов в C#
Составные части объектного подхода
Языки программирования
Делегаты
Chislovye tipy dannykh_i_ikh_ispolzovanie_v_vba
Интерфейсы
Безопасное программирование на C#
DevPro-2014: Кроссплатформенное приложение за 15 минут или Беды и победы моби...
язык программирования с#
Luxoft async.net
Наследование и полиморфизм
Презентация курса "Основы программирования" на C#
Ad

Similar to О сложностях программирования, или C# нас не спасет? (20)

PPTX
C#. От основ к эффективному коду
PDF
Распространённые ошибки оценки производительности .NET-приложений
PDF
Распространённые ошибки оценки производительности .NET-приложений
PPTX
Deep Dive C# by Sergey Teplyakov
PPTX
Фофанов Илья - Лучшие практики проектирования и реализации API на C#
PDF
Поиск и чтение унаследованного кода
PDF
PVS-Studio в 2021 - Примеры ошибок
PPT
Обзор платформы B4
PPTX
разработка бизнес приложений (8)
PPT
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
PPTX
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
ODP
PDF
C# Desktop. Занятие 04.
PPTX
C sharp deep dive
PPTX
C# Deep Dive
PDF
Продолжаем говорить о микрооптимизациях .NET-приложений
PDF
MullC#.pdf
PDF
Поговорим о микрооптимизациях .NET-приложений
PDF
Игорь Лабутин «Коллекционируем данные в .NET»
C#. От основ к эффективному коду
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложений
Deep Dive C# by Sergey Teplyakov
Фофанов Илья - Лучшие практики проектирования и реализации API на C#
Поиск и чтение унаследованного кода
PVS-Studio в 2021 - Примеры ошибок
Обзор платформы B4
разработка бизнес приложений (8)
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
C# Desktop. Занятие 04.
C sharp deep dive
C# Deep Dive
Продолжаем говорить о микрооптимизациях .NET-приложений
MullC#.pdf
Поговорим о микрооптимизациях .NET-приложений
Игорь Лабутин «Коллекционируем данные в .NET»

More from Tatyanazaxarova (20)

PDF
Урок 27. Особенности создания инсталляторов для 64-битного окружения
PDF
Урок 26. Оптимизация 64-битных программ
PDF
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
PDF
Урок 24. Фантомные ошибки
PDF
Урок 23. Паттерн 15. Рост размеров структур
PDF
Урок 21. Паттерн 13. Выравнивание данных
PDF
Урок 20. Паттерн 12. Исключения
PDF
Урок 19. Паттерн 11. Сериализация и обмен данными
PDF
Урок 17. Паттерн 9. Смешанная арифметика
PDF
Урок 16. Паттерн 8. Memsize-типы в объединениях
PDF
Урок 15. Паттерн 7. Упаковка указателей
PDF
Урок 13. Паттерн 5. Адресная арифметика
PDF
Урок 11. Паттерн 3. Операции сдвига
PDF
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
PDF
Урок 9. Паттерн 1. Магические числа
PDF
Урок 8. Статический анализ для выявления 64-битных ошибок
PDF
Урок 7. Проблемы выявления 64-битных ошибок
PDF
Урок 6. Ошибки в 64-битном коде
PDF
Урок 5. Сборка 64-битного приложения
PDF
Урок 4. Создание 64-битной конфигурации
Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 26. Оптимизация 64-битных программ
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 24. Фантомные ошибки
Урок 23. Паттерн 15. Рост размеров структур
Урок 21. Паттерн 13. Выравнивание данных
Урок 20. Паттерн 12. Исключения
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 17. Паттерн 9. Смешанная арифметика
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 15. Паттерн 7. Упаковка указателей
Урок 13. Паттерн 5. Адресная арифметика
Урок 11. Паттерн 3. Операции сдвига
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 9. Паттерн 1. Магические числа
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
Урок 6. Ошибки в 64-битном коде
Урок 5. Сборка 64-битного приложения
Урок 4. Создание 64-битной конфигурации

О сложностях программирования, или C# нас не спасет?

  • 1. О сложностях программирования, или C# нас не спасет? Автор: Евгений Рыжков Дата: 26.10.2010 Программирование это сложно. С этим никто, надеюсь, не спорит. Но вот тема новых языков программирования, а точнее поиск "серебряной пули" всегда находит бурных отклик в умах разработчиков программного обеспечения. Особенно "модной" является тема превосходства одного языка программирования над другим. Ну, к примеру, что C# "круче", чем C++. И хотя holy wars – это не та причина, по которой я пишу этот пост, тем не менее, что называется "наболело". Ну не поможет C#/lisp/F#/Haskell/... написать изящное приложение, взаимодействующее с внешним миром, и все тут. Вся изящность теряется, стоит захотеть написать что-то реальное, а не пример "сам в себе". В тексте несколько фрагментов на C#, взятые из модуля интеграции статического анализатора кода PVS-Studio в популярную среду Microsoft Visual Studio. Этими фрагментами я хочу показать, что писать, к примеру, на C# совсем не проще, чем на, C++. Простой combobox Этак, первый фрагмент кода – обработка выбора одной из трех строк в ОБЫЧНОМ combobox на панели инструментов с картинки. Рисунок 1 – Простой combobox на три строчки И вот для обработки такой вот фитюльки требуется следующий код. К сожалению, пришлось изменить форматирование и убрать комментарии. Так что прошу прощения за ужас. private void OnMenuMyDropDownCombo(object sender, EventArgs e) { if (e == EventArgs.Empty) { throw (new ArgumentException());
  • 2. } OleMenuCmdEventArgs eventArgs = e as OleMenuCmdEventArgs; if (eventArgs != null) { string newChoice = eventArgs.InValue as string; IntPtr vOut = eventArgs.OutValue; if (vOut != IntPtr.Zero && newChoice != null) { throw (new ArgumentException()); } else if (vOut != IntPtr.Zero) { Marshal.GetNativeVariantForObject( this.currentDropDownComboChoice, vOut); } else if (newChoice != null) { bool validInput = false; int indexInput = -1; for (indexInput = 0; indexInput < dropDownComboChoices.Length; indexInput++) { if (String.Compare( dropDownComboChoices[indexInput], newChoice, true) == 0)
  • 3. { validInput = true; break; } } if (validInput) { this.currentDropDownComboChoice = dropDownComboChoices[indexInput]; if (currentDropDownComboChoice == Resources.Viva64) UseViva64Analysis(null, null); else if (currentDropDownComboChoice == Resources.GeneralAnalysis) UseGeneralAnalysis(null, null); else if (currentDropDownComboChoice == Resources.VivaMP) UseVivaMPAnalysis(null, null); else { throw (new ArgumentException()); } } else { throw (new ArgumentException()); } } else
  • 4. { throw (new ArgumentException()); } } else { throw (new ArgumentException()); } } Причем здесь IntPtr.Zero и Marshal.GetNativeVariantForObject()? Ну так надо... Простой combobox обрабатывается совсем не просто. Причем этого кода не достаточно. Есть еще рядом функция OnMenuMyDropDownComboGetList() примерно такого же размера. Здесь C# оказался ничем не лучше любого другого языка. Нет, конечно же, круто, что он инкапсулировал от меня OLE, маршалинг. На Си все было бы намного печальней. Но вот только как-то все равно все не то, как преподносится в книгах и эвангелистами. Простота-то где? Я всего лишь хотел с выпадающим списком поработать. Навигация по коду в Visual Studio Когда в Visual Studio вы щелкаете по сообщению об ошибке, срабатывает примерно такой код для открытия файла и перехода к строке с ошибкой. public void OpenDocumentAndNavigateTo(string path, int line, int column) { IVsUIShellOpenDocument openDoc = Package.GetGlobalService( typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; if (openDoc == null) return; IVsWindowFrame frame; Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp; IVsUIHierarchy hier;
  • 5. uint itemid; Guid logicalView = VSConstants.LOGVIEWID_Code; if (ErrorHandler.Failed( openDoc.OpenDocumentViaProject(path, ref logicalView, out sp, out hier, out itemid, out frame)) || frame == null) return; object docData; frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out docData); VsTextBuffer buffer = docData as VsTextBuffer; if (buffer == null) { IVsTextBufferProvider bufferProvider = docData as IVsTextBufferProvider; if (bufferProvider != null) { IVsTextLines lines; ErrorHandler.ThrowOnFailure( bufferProvider.GetTextBuffer(out lines)); buffer = lines as VsTextBuffer; if (buffer == null) return; } } IVsTextManager mgr = Package.GetGlobalService(typeof(VsTextManagerClass)) as IVsTextManager; if (mgr == null)
  • 6. return; mgr.NavigateToLineAndColumn( buffer, ref logicalView, line, column, line, column); } Ё-мое... Ужас. Набор магических заклинаний. Этот код, будучи написанным на C#, опять же ничем не упростил жизнь своему разработчику. Кто скажет, что это будет лучше выглядеть на языке XYZ? Язык здесь "перпендикулярен" к решаемой задаче и практически не оказывает влияния. Работа с датой Ну, уж работа с датами в C# должна быть точно на высоте! Ведь там столько разных удобных форматов сделали. Думал я, до тех пор, пока из внешней программы не пришло время в формате __time64_t, а в C# коде необходимо было использовать класс DateTime. Конвертировать __time64_t в DataTime конечно не сложно, для этого всего лишь надо написать функцию типа такой: public static DateTime Time_T2DateTime(long time_t) { //116444736000000000 - это 1600 год long win32FileTime = 10000000 * time_t + 116444736000000000; return DateTime.FromFileTime(win32FileTime); } И здесь C# оказался ничем не лучше... Возможно конечно я не нашел функцию конвертации. Ну, неужели нельзя было у DateTime нужный конструктор сделать? Ну почему, как взаимодействие с окружающей средой, так опять все по старинке "ручками" делать приходится? Перебор всех проектов одного решения (solution) Для некоторой задачи необходимо перебрать все проекты, которые есть в решении (Visual Studio solution). Вместо простого и элегантного foreach код выглядит так: Solution2 solution = PVSStudio.DTE.Solution as Solution2; SolutionBuild2 solutionBuild = (SolutionBuild2)solution.SolutionBuild; SolutionContexts projectContexts = solutionBuild.ActiveConfiguration.SolutionContexts;
  • 7. int prjCount = projectContexts.Count; for (int i = 1; i <= prjCount; i++) { SolutionContext projectContext = null; try { projectContext = projectContexts.Item(i); } catch (Exception) { // try/catch block is a workaround. // It's needed for correct working on solution // with unloaded projects. continue; } ... Во-первых, оказывается, что foreach для этого класса недоступен. Но ладно, for-ом пользоваться еще не разучились. Во-вторых, если обратиться к элементу, который в наборе есть, но у него "не очень корректное" состояние – то летит исключение. В результате код заметно усложняется. А код на C# опять ничем не отличается от кода на другом языке. Выводы Данным постом я хотел показать, что далеко не всегда код на C# (или другом языке) проще, чем код на C/C++. И поэтому слепо верить в то, что "надо все переписать на C#" не нужно. Тем не менее, я совершенно не считаю, что "C# - отстой", поскольку во многих местах он действительно упрощает жизнь. В чем причины того, что указанные в посте фрагменты кода выглядят также сложно, как и на C++? 1. Взаимодействие с различными API. Например, как здесь было взаимодействие с Visual Studio API. 2. Взаимодействие с программами на других языках. Например, тип __time64_t конечно же пришел от C++-приложения. 3. Взаимодействие с операционной системой. Далеко не всегда удается состыковать красивый и правильный C#-код с реальностью в лице Windows. 4. Несовершенство алгоритмов обработки данных. Если вы работаете со строками, то от "+1" в коде вы никуда не денетесь, на каком бы языке вы не писали.
  • 8. Оправдания по использованному в примерах коду: 1. Комментарии вырезаны, код сокращен до минимально необходимого в статье. 2. Да, авторы кода не умеют писать на C#, но от этого C# не становится волшебнее.