На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> C++/CLI vs C# , Ваше мнение.
    Вопрос таков:
    В чем схожести и в чем различия, а также плюсы и минусы данных .NETовских языков.

    Хочу выяснить для того, чтобы решить имеет ли смысл заморачиватся вообще на C# при разработках под .NET, или являясь С++ программистом достаточно просто изучить особенности программирования под .NET на C++/CLI, как альтернативе C#?
    Сообщение отредактировано: developer -
      Очередной холивар. Будет постов на несколько страниц.
      developer, погугли.
        Не холивар, а конкретный вопрос требующий конкретного ответа. Интересны все мнения про особенности между двумя языками, так как о C# представление 0, а о C++/CLI наработана уже хоть и небольшая но база знаний.
        Главный вопрос: Большая ли разница между этими двумя языками?
        И есть ли вещи которые может делать один язык и не может делать другой?
        Сообщение отредактировано: developer -
          Между NET и nonNET - большая.
          А какие у тебя наработки по C++? Знание STL, навыки работы с указателями, знание WinAPI? Все, что отсюда понадобится, это знание ООП и все.
          Здесь в разделе иногда мелькают вопросы-примеры на C++, я таких людей не понимаю. Visual Basic - один человек хорошо отозвался - "простыня слов". А C# - просто и элегантно :)
            Цитата Raino @
            Между NET и nonNET - большая.
            А какие у тебя наработки по C++? Знание STL, навыки работы с указателями, знание WinAPI? Все, что отсюда понадобится, это знание ООП и все.

            Это все философия про ISO/ANSI С++ итак понятная и вообще я не спрашивал про разницу между ISO/ANSI С++ и C++/CLI, а причем сдесь VB я вообще не понял :D .

            Вопрос конкретный: разница между двумя .NET-овскими языками C++/CLI end C#.
            Сообщение отредактировано: developer -
              Цитата Raino @
              навыки работы с указателями, знание WinAPI

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

              Вот могу привести пример номер один. На C++/CLI нельзя по человечески писать для web с ASP.NET, вернее можно, но довольно геморно. Аналогично обстоят дела и с новомодными Silverlight и ижи с ними. Там IronPython поддерживаются лучше, чем плюс-плюс.

              Цитата developer @
              или являясь С++ программистом достаточно просто изучить особенности программирования под .NET на C++/CLI, как альтернативе C#?

              Для таких как ты его и создавали :)

              К плюсам плюсов (во какой каламбурчик :) ) отнес бы незначительно более производительный компилятор (3-5% от C#) и наверное более удобную модель маршалинга к нативному коду, вот собственно и все приимущества C++/CLI если рассматривать платформу .NET.

              Во всем остальном, C# и VB.NET ИМХО проще, а главное лаконичней чем C++/CLI, а потому эффективней в рамках .NET. Это языки позволяющие не задумываться о языке на котором пишешь. Они позволяют сосредоточиться на тех задачах, что ты решаешь. Наверное по этому почти весь Framework написан именно на C#.

              Добавлено
              Вот еще пришло в голову на ++ тебе будет проблематично писать плагины к офиссным приложениям, создавать WPF, WCF проекты. Ввсе это можно делать, но в студии ты не найдешь даже визардов проектов для этого...


              Цитата
              а причем сдесь VB я вообще не понял .

              И малость оффтопа .. оказывается в Integration Service 2005 сиквел сервера, скрипты в Сontrol flow .. можно писать только на VB.NET.
              Сообщение отредактировано: juice -
                juice
                Насчет указателей я имел ввиду, что не считаю динамические переменные в C++ аналогом объектов reference-типов. А знание структур на c++ только собьет с толку. Поэтому думаю лучше уже учить синтаксис .NET с нуля, не ссылаясь на прошлый опыт. А сама концепция программирования, что в памяти что-то хранить, изменять, что есть классы-методы, это я все и обобщил "ООПом" :)
                  Цитата juice @
                  К плюсам плюсов (во какой каламбурчик :) ) отнес бы незначительно более производительный компилятор (3-5% от C#) и наверное более удобную модель маршалинга к нативному коду, вот собственно и все приимущества C++/CLI если рассматривать платформу .NET.

                  То есть насколько я понял из этой части ответа реализация CLI уже существует не только в виде реализации CLR для .NET Framework, но и для других платформ?
                  Интересно, а для каких еще?
                    Цитата developer @
                    То есть насколько я понял из этой части ответа реализация CLI уже существует не только в виде реализации CLR для .NET Framework, но и для других платформ?

                    на самом деле при компиляции кода в MSIL каждый язык использует собственный компилятор. Отсюда ращница. Компилятор для ++ дает несколько более производительный код, чем компилятор C#, в тоже время последний самую малость выигрывает у VB.NET. Под платформой .NET я имел ввиду рассмотрение исключительно Managed версии C++.

                    Вообщето откровенно говоря CLR не совсем следует собственной спецификации Microsoft - CLI (стандартизированной в ECMA, например отличается модель памяти, в CLR используется сильная модель в отличие от слабой модели описываемой в CLI), но если откинуть нюансы, то есть реализациb CLI под Linux/Windows/Mac OS - Mono и Rotor под Unix.
                      Вопрос объявляю решенным и тему закрытой.
                      Ответами доволен, особенно четкими и лаконичными ответами "по делу" участника juice .

                      В общем С++/CLI меня теперь вполне устраивает как язык для приложений под .NET Framework.

                      GRIENDERS, и ни каких релегиозных войн не произошло :P .
                        Цитата developer @
                        В общем С++/CLI меня теперь вполне устраивает как язык для приложений под .NET Framework.

                        Твой выбор одобряю. Но думаю, ты скоро (ну или со временем) начнешь писать на C# под .NET ;) Свой прогноз я основываю на том, что многие проффи С++ (FlexFerum, Loviard e.t.c) сайта sources.ru, под .NET пишут именно на шарпе, думаю их выбор небезоснователен и чем то мотивирован ... :)

                        P.S. Ну и успехов в освоени новых вершин :)
                        Сообщение отредактировано: juice -
                          Цитата
                          В общем С++/CLI меня теперь вполне устраивает как язык для приложений под .NET Framework.

                          учти что большинство примеров на С#...вот сейчас сам из-за этого мучаюсь.И честно сложилось впечатление что С# это почти синоним .NET
                            ИМХО, как минимум, читать необходимо и на том и на другом языке.

                            С точки зрения программирования "высокоскоростных" приложений
                            лучше юзать managed C++ В виду его хорошей совместимости с unmanaged,
                            ассемблерным вставками и т.п. Кроме того с С++ (старой версии) можно
                            использовать OpenMP!!! Это большой плюс для применения параллельных алгоритмов.

                            С другой стороны C# имеет более простой синтаксис и структуру и т.п.
                            Быстро компилируется и, соответсвенно, оперативно показывает
                            подсказки для функций (интелисенс). Короче кодить удобно.

                            Так что для прог не особо критичных ко времени выполнения, не требующих сторонних
                            С++ библиотек, лучше юзать C#.
                              Цитата
                              В виду его хорошей совместимости с unmanaged,
                              ассемблерным вставками и т.п.

                              Это вероятно самый весомый аргумент.
                                Цитата juice @
                                Во всем остальном, C# и VB.NET ИМХО проще, а главное лаконичней чем C++/CLI

                                И возня с using лаконичнее возможности размещения объектов "на стеке" в C++/CLI?
                                  Цитата Hryak @
                                  И возня с using лаконичнее возможности размещения объектов "на стеке" в C++/CLI?

                                  Ты приводишь практически частный случай, когда из C# приходиться работать с неуправляемыми ресурсами, причем с using возиться, не всегда и обязательно.

                                  По сути все удобства от C++/CLI на платформе .NET как раз и заканчиаются. Там где заканчиваются врапперы для обращения к нативному коду. ИМХО.

                                  Пекарю пекарево, а кесарю кесарево. С++ был и остается стандартом в системном программировании. Не вижу повода зная С++ заморачиваться с ним при программировании бизнесс приложений. Каждой задаче свой инструмент. И если расматривать С++/CLI как язык для системного программирования, то честно говоря не вижу причин не писать на unmanaged С++.
                                    Цитата juice @
                                    Ты приводишь практически частный случай, когда из C# приходиться работать с неуправляемыми ресурсами, причем с using возиться, не всегда и обязательно.

                                    SqlConnection - неуправляемый ресурс? :wacko: И ты при работе с ним не используешь using ?
                                      Цитата Hryak @
                                      Цитата juice @
                                      Во всем остальном, C# и VB.NET ИМХО проще, а главное лаконичней чем C++/CLI

                                      И возня с using лаконичнее возможности размещения объектов "на стеке" в C++/CLI?

                                      А можешь написать пример возни с "using" и красивого кода на C++/CLI
                                        Цитата Hryak @
                                        SqlConnection - неуправляемый ресурс?

                                        Смотря, что ты под этим понимаешь. Сам объект распологается в управляемой куче. И будет собран сборщиком мусора. Другой вопрос, что после того, как ты с его помощью открыл физическое соединение с БД, ты должен его явно закрыть. Ты ведь вызываешь fclose для файлов? Т.к. сборщик мусора управляет памятью, а не физ. соединениями БД. Как ты это сделаешь, с помощью метода Close или Dispose не важно, но закрыть ты его должен. Альтернативой может быть реализация IDisposible в классе и управление тогда перекладывается на него и\или финалайзер. Тут уже скорее вопрос дизайна.


                                        Цитата Hryak @
                                        ты при работе с ним не используешь using ?

                                        using по сути неявно генерит код c finaly, где будет вызыван метод Dispose. Лично я предпочитаю использовать явный вызов Dispose, но часто бывает, что объект SqlConnection, мне нужен в проинициализированном сотоянии для дальнейшей работы и я просто вызываю метод Close, а Dispose объкта SqlConnection вызывается уже в методе объекта реализующего IDisposible и позже по месту или вообще не вызывается оставаясь добычей сборщика мусора, главное, что бы ты закрыл физический конект к БД. Если будешь настаивать я проведу тебе лекцию по этому поводу, точно так же как и расскажу разнцу между методом Close и Dispose и зачем нужен using.
                                          Ну я под .НЕТ пишу только на шарпе. А C++/CLI использую только чтобы обертывать требовательные по скорости модули, реализованные на чистом С++. Модули на чистом Си я могу обернуть и в шарпе интероп сервисами. Ну или использую C++/CLI для требовательного по скорости алгоритма реализуя внутренности методов .НЕТ объектов на чистом С++, если знаю что эта функциональность понадобится только в .НЕТе и не надо будет алгоритм импортировать в другие нативные модули... Также можно использовать C++/CLI для обертки большого куска Вин АПИ, это иногда проще чем интеропить кучу функций, тем более что этот кусок можно сразу сделать ООПным... Хотя чаще все же копи-пастю из Рефлектора то, что уже давно интеропнуто в System.Windows.Forms, только заприватено там внутри.

                                          В общем, каждый язык для своей задачи. Я ж не дурак писать на C++/CLI интерфейс на винформз :D :D :D Но пару раз было писал отдельные сложные контролы на Managed C++ скрещивая Вин АПИ и ВинФормз, особенно когда нужно было, чтобы они не только ГДИ+ использовали, но и темы ХР.... Однако щас лучше буду использовать из шарпа свой класс C++/CLI интеропящий работу с темами из Visual Styles API...

                                          Блин ну насколько же раньше проще было писать MC++ вместо нынешнего C++/CLI :(

                                          Добавлено
                                          Ответ на это: Предпочитаемый .NET язык (сообщение #1944531) :)
                                          Цитата developer @
                                          Может C++/CLI и не самый лучший и идеальный .NET-совместимый язык, но для тех кто работал или работает с ISO/ANSI C++ на мой вгляд неплохой вариант.
                                          К слову говоря, когда Микрософт разрабатывали C++/CLI в их задачу входило сделать его максимально несовместимым с ISO/ANSI C++ :D :D :D От них этого потребовал комитет С++, чтобы Микрософт ни в коем случае не затронул будущие версии С++, код в которых мог бы неоднозначно компилироваться...
                                            Loviard, соглашусь с тобой. С++/CLI имеет более широкие возможности по взаимодействию с неуправляемым кодом, более того он еще и работает быстрее с ним чем вызовы через PInvoke драйвер.

                                            Цитата Loviard @
                                            К слову говоря, когда Микрософт разрабатывали C++/CLI в их задачу входило сделать его максимально несовместимым с ISO/ANSI C++

                                            Прикольно. Я почему то считал, что это версия Managed C++ (в VS 2003) была такой. А для VS 2005, разрабатывался по сути новый язык С++/CLI на основе старого Managed C++ Extention и вроде теперь заявляется поддержка стандарта. Или ты имеешь ввиду именно ту часть языка, что относится непосредственно к возможностям .NET C++/CLI?
                                              Цитата Raino @
                                              А можешь написать пример возни с "using" и красивого кода на C++/CLI

                                              Писать не буду, сам представь - пяток вложенных using для организации детерминированного разрушения объектов или ни одного.

                                              Цитата
                                              Ты ведь вызываешь fclose для файлов?

                                              Представь себе, не вызываю. Всё само делается, даже если произошло исключение и идет раскрутка стека. Безо всяких try / finally

                                              Цитата
                                              using по сути неявно генерит код c finaly, где будет вызыван метод Dispose.

                                              Я в курсе.

                                              Цитата
                                              Лично я предпочитаю использовать явный вызов Dispose

                                              В finally блоке? Не напрягает?

                                              Цитата
                                              Если будешь настаивать я проведу тебе лекцию по этому поводу, точно так же как и расскажу разнцу между методом Close и Dispose и зачем нужен using.

                                              Не буду настаивать. Разницу между Close и Dispose я и так понимаю, а по поводу прочего - у нас слишком разные идеологии, чтобы ты мне что-нибудь смог доказать. Я люблю использовать автоматические объекты и не париться по поводу - а нужно ли ручками освобождать ресурс или нет. Я рад, что и в .NET я могу их использовать благодаря С++/CLI.

                                              В эту дискуссию я влез не для того, чтобы доказывать, что С++/CLI немерянно крут, просто указал на одну немаловажную деталь, про которую тут все забыли.

                                              Цитата
                                              Блин ну насколько же раньше проще было писать MC++ вместо нынешнего C++/CLI

                                              Вот уж действительно - каждому свое... :wacko: :wacko: :wacko:

                                              Цитата
                                              К слову говоря, когда Микрософт разрабатывали C++/CLI в их задачу входило сделать его максимально несовместимым с ISO/ANSI C++ От них этого потребовал комитет С++, чтобы Микрософт ни в коем случае не затронул будущие версии С++, код в которых мог бы неоднозначно компилироваться...

                                              Не ставь всё с ног на голову. При чем тут несовместимость?? Сейчас все совместимо, а требовалось, спецификация не мешала развитию С++.
                                                Цитата Hryak @
                                                Писать не буду, сам представь - пяток вложенных using для организации детерминированного разрушения объектов или ни одного.

                                                Допускаю, что столь сильный девелопер (без иронии) знает почему в .NET нет детерминированого уничтожения объектов. Кстати хочу тебя поправить, вызов Dispose не приводит к разрушению .NET объекта... Его корректное дальнейшее использование (вернее не использование) на совести того, кто реализовывал IDisposible.

                                                Цитата Hryak @
                                                Представь себе, не вызываю. Всё само делается

                                                Прикольно. Мне действительно интересно. Каким таким волшебным образом закроется физическое соединение с БД, без явного вызова Close, после освобождения памяти которое объект занимал в стеке, до того как он вышел из области видимсти?

                                                Цитата Hryak @
                                                Писать не буду, сам представь - пяток вложенных using для организации детерминированного разрушения объектов или ни одного.

                                                Тогда вопрос, что тебе мешает явно вызывать Dispose не используя конструкцию с using? По пять штук кряду ... слабовато представляю. Видел обычно по парочке и при работе в GDI+. А там к слову гораздо эффективней переопределять Dispose или реализовывать IDisposible, чем создавать кисти и перья локально в методах. Преимуществ масса жрет меньше памяти да и работает быстрее.
                                                Сообщение отредактировано: juice -
                                                  Цитата juice @
                                                  Или ты имеешь ввиду именно ту часть языка, что относится непосредственно к возможностям .NET C++/CLI?
                                                  Ну да конечно, может я нечетко выразился, но само собой именно это и имел в виду...

                                                  Цитата juice @
                                                  Прикольно. Я почему то считал, что это версия Managed C++ (в VS 2003) была такой.
                                                  Наоборот, если сравнить Managed Extensions for C++ и C++/CLI, то получается, что почти любую конструкцию MC++ (может за исключением __identifier) можно так или иначе, макросами например, свести к Чистому С++. Любые __gc, __pin, __box можно объявить через дефайны как пустое место или еще что... Даже свойства по сути дела, те же методы нормально скомпилировались бы... А в C++/CLI как ни пытайся, а со ссылкой ^ или с новым синтаксисом свойста ничего поделать не сможешь, чтобы оно скомпилировалось на Чистом С++. Или никаким новым зарезервированным словом Микрософт не перебьет будущие зарезервированные слова или просто идентификаторы, потому что все (или почти все) новые зарезервированные слова содержат пробел. Ведь ref class не является двумя зарезервированными словами, это одно с "разделителем". По отдельности они не подсвечиваются и их можно использовать в качестве своих идентификаторов...

                                                  Цитата Hryak @
                                                  Не ставь всё с ног на голову. При чем тут несовместимость?? Сейчас все совместимо, а требовалось, спецификация не мешала развитию С++.
                                                  А что я с ног на голову поставил?
                                                    Loviard, cспасибо за комментарии.
                                                      Цитата juice @
                                                      знает почему в .NET нет детерминированого уничтожения объектов.

                                                      Таков применяемый GC? Правда, это можно рассмотреть и с другой стороны - объекты уничтожаются, когда будет время, которое можно потратить на их уничтожение. :)

                                                      Цитата
                                                      Кстати хочу тебя поправить, вызов Dispose не приводит к разрушению .NET объекта...

                                                      Естественно, он "разрушает" объект с точки зрения программной логики (освобождает ресурсы и т.п.)

                                                      Цитата
                                                      Каким таким волшебным образом закроется физическое соединение с БД, без явного вызова Close, после освобождения памяти которое объект занимал в стеке, до того как он вышел из области видимсти?

                                                      Почему до выхода из области видимости? При выходе из области видимости...

                                                      Цитата
                                                      Тогда вопрос, что тебе мешает явно вызывать Dispose не используя конструкцию с using?

                                                      Потому что команда где-то перед вызовом Dispose могла кинуть исключение и этот Dispose никогда не выполнится. Заворачивать же все в try / finally - загромождать код.

                                                      Цитата Loviard @
                                                      А что я с ног на голову поставил?

                                                      Цитата Loviard @
                                                      когда Микрософт разрабатывали C++/CLI в их задачу входило сделать его максимально несовместимым с ISO/ANSI C++
                                                        Цитата Hryak @
                                                        А что я с ног на голову поставил?
                                                        Hryak, еще раз повторяю свой вопрос.
                                                          Цитата Hryak @
                                                          Таков применяемый GC? Правда, это можно рассмотреть и с другой стороны - объекты уничтожаются, когда будет время, которое можно потратить на их уничтожение.

                                                          Вполне, но это несколько далековато от тематики обсуждения.

                                                          Цитата Hryak @
                                                          Почему до выхода из области видимости?

                                                          Потому, что память он там занимал именно тогда когда был в области видимости :) Перечитай внимательней. Кстати там был и вопрос. Я повторюсь. Как ты закроешь физическое подключение, расположив SqlConnection на стеке при этом не вызвав явно метод Close? Считай, что мне любопытно, я не гуру в C++/CLI, а потому интересуюсь.

                                                          Цитата Hryak @
                                                          Потому что команда где-то перед вызовом Dispose могла кинуть исключение и этот Dispose никогда не выполнится. Заворачивать же все в try / finally - загромождать код.

                                                          Я это прекрасно понимаю. Я приводил альтернативное решение с IDisposible, тем не менее даже в этом случае, то как будет конкретно написан код, зависит от того, как реализуется политика обработки исключений в приложении.

                                                          Ну и на последок согласись, что восемь вложенных using при работе с БД, через ADO.NET это через край фантастично.
                                                            Цитата juice @
                                                            Считай, что мне любопытно, я не гуру в C++/CLI, а потому интересуюсь.
                                                            Ну там действительно не-value объекты можно располагать в стэке.
                                                              Цитата Loviard @
                                                              Ну там действительно не-value объекты можно располагать в стэке.

                                                              Я понимаю. Я хочу понять как будет закрываться при этом физическое подключение если для него не использовать using/Dispose или Close, мои скромные познания С++/CLI сводятся к тому, что код можно записать примерно так:

                                                              ExpandedWrap disabled
                                                                     auto_handle<SqlConnection> connection = gcnew SqlConnection(myConnString);
                                                                     connection->Open();
                                                                 
                                                                     auto_handle<SqlCommand> command = gcnew SqlCommand("запрос", connection);
                                                                 
                                                                     ...
                                                                 
                                                                     auto_handle<SqlDataReader> reader = command->ExecuteReader();
                                                                     while(reader->Read())
                                                                     {
                                                                          ...
                                                                     }


                                                              При этом все отлично отработает и соединение закроется. Но на выделение памяти в стеке это не похоже или я ошибаюсь ? :)
                                                              Вот я и спрашиваю, уважаемогоHryak, как сделать то о чем он говорит.
                                                              Сообщение отредактировано: juice -
                                                                Цитата Loviard @
                                                                Ну там действительно не-value объекты можно располагать в стэке.
                                                                На самом деле я наврал конечно, объект будет располагаться все равно в куче, но вести себя будет как объект расположенный в стеке (семантика стека). В конце метода компилером будет вставлен код вызова финализатора объекта. Так что выглядеть это будет так...
                                                                ExpandedWrap disabled
                                                                  void Foo()
                                                                  {
                                                                    SqlConnection connection (myConnString);
                                                                    SqlDataReader reader = connection.ExecuteReader();
                                                                    // ... работаем
                                                                  } // вызовутся финализаторы


                                                                Добавлено
                                                                Цитата Loviard @
                                                                В конце метода компилером будет вставлен код вызова финализатора объекта
                                                                Однако я опять наврал :D :D :D Вызовется именно IDisposable.Dispose, просто в C++/CLR он имеет синтаксис деструктора. Вообще там все так интересно построено...

                                                                Вот мой код класса:
                                                                ExpandedWrap disabled
                                                                  public ref class A
                                                                  {
                                                                  public:
                                                                      A()
                                                                      {
                                                                          Console::WriteLine("A::A();");
                                                                      }
                                                                   
                                                                      ~A() // деструктор, а на самом деле Dispose
                                                                      {
                                                                          Console::WriteLine("A::~A();");
                                                                      }//*/
                                                                   
                                                                      !A() // финализатор
                                                                      {
                                                                          Console::WriteLine("A::!A();");
                                                                      }//*/
                                                                   
                                                                      void f()
                                                                      {
                                                                          Console::WriteLine("A::f();");
                                                                      }
                                                                  };


                                                                А вот то, что из него сотворил компилятор:
                                                                (Рефлектор пока только MC++ знает :( )
                                                                ExpandedWrap disabled
                                                                  public __gc class A : public IDisposable
                                                                  {
                                                                      // Methods
                                                                      private: void __gc* !A() // компилер превратил в обычный метод, добавил возвращаемый тип, хотя в коде синтаксис этого не требует...
                                                                      {
                                                                          Console::WriteLine(S"A::!A();");
                                                                      }
                                                                   
                                                                      public: A()
                                                                      {
                                                                          Console::WriteLine(S"A::A();");
                                                                      }
                                                                   
                                                                      private: void __gc* ~A()
                                                                      {
                                                                          Console::WriteLine(S"A::~A();");
                                                                      }
                                                                   
                                                                      public: sealed override void __gc* Dispose()
                                                                      {
                                                                          this->Dispose(true);
                                                                          GC::SuppressFinalize(this);
                                                                      }
                                                                   
                                                                      protected: virtual void __gc* Dispose([MarshalAs(UnmanagedType::U1)] Boolean __gc* flag1)
                                                                      {
                                                                          if (flag1)
                                                                          {
                                                                              this->~A();
                                                                          }
                                                                          else
                                                                          {
                                                                              try
                                                                              {
                                                                                  this->!A();
                                                                              }
                                                                              finally
                                                                              {
                                                                                  base->Finalize();
                                                                              }
                                                                          }
                                                                      }
                                                                   
                                                                      public: void __gc* f()
                                                                      {
                                                                          Console::WriteLine(S"A::f();");
                                                                      }
                                                                   
                                                                      protected: override void __gc* Finalize()
                                                                      {
                                                                          this->Dispose(false);
                                                                      }
                                                                   
                                                                  };


                                                                Дописав в класс "деструктор" ~A() компилер автоматически порождает мой класс от IDisposable и добавляет код его реализации...
                                                                  Loviard, thx. Сбор мусора как был недетерминированым таким и остался по своей сути, ожидать чего то другого было бы странно при размещении объектов в управляемой куче.
                                                                    А вот реализация метода f(), в котором я деструктор проверял:
                                                                    мой код:
                                                                    ExpandedWrap disabled
                                                                      void f()
                                                                      {
                                                                          A a;
                                                                          a.f();
                                                                      }


                                                                    Рефлектор:
                                                                    ExpandedWrap disabled
                                                                      public private: static void __gc* modopt(CallConvCdecl __gc*) f()
                                                                      {
                                                                          A __gc* a = 0;
                                                                          A __gc* modopt(IsConst __gc*) a2 = __gc new A();
                                                                          try
                                                                          {
                                                                              a = a2;
                                                                              a->f();
                                                                          }
                                                                          fault
                                                                          {
                                                                              a->Dispose();
                                                                          }
                                                                          a->Dispose();
                                                                      }
                                                                    Вообщем ужос :) Объект конечно удален не будет, но путем нескольких извратов компилер вызовет Dispose...
                                                                      Loviard, вот смотри какая любопытная фича, при выходе из области видимости объекта A,

                                                                      Например код метода f в классе B

                                                                      ExpandedWrap disabled
                                                                            void f()
                                                                            {
                                                                                A a;
                                                                                a.f();
                                                                            }


                                                                      вызывается его деструктор, но не Dispose, а это наталкивает на одну очень интересную, на мой взгляд мысль, что если пользоваться "семантикой стека" с объектом вроде SqlConnection, то это в конечном итоге, привидет к эффекту достигаемому, когда Close или Dispose вообще явно не вызываются. Как следствие Close отработает при вызове Dispose тогда когда этот объект будет размещен в очередь для выполнения финалайзера... а это произойдет только тогда когда сборщик мусора определит, что объект является мусором. При этом реальное освобождение памяти вообще произойдет при следующем проходе GC.

                                                                      Добавлено
                                                                      Loviard ты опередил, я только хотел посмотреть во-что это скомпилится. Оказывается Dispose таки вроде как вызывается.
                                                                        Не... при выходе из метода вызовется то как раз Dispose, просто в С++/CLI по синтакису Dispose является деструктором (а финалайзер отдельно). Более того, они как-то странно это сделали. Ты можешь отнаследовать класс от IDisposable, но компилер запретит тебе написать метод с названием Dispose. Тебе только можно написать метод ~A() ...А компилер сам реализetn Dispose и вызовет в нем ~A() как показано выше. А при выходе из метода вызовет именно IDisposable.Dispose
                                                                          Цитата Loviard @
                                                                          компилер вызовет Dispose...


                                                                          И закроет соединение:
                                                                          Вот код из SqlConnection

                                                                          ExpandedWrap disabled
                                                                            protected: override void __gc* Dispose(Boolean __gc* disposing)
                                                                            {
                                                                                if (disposing)
                                                                                {
                                                                                    this->_userConnectionOptions = 0;
                                                                                    this->_poolGroup = 0;
                                                                                    this->Close();
                                                                                }
                                                                                this->DisposeMe(disposing);
                                                                                base->Dispose(disposing);
                                                                            }
                                                                          Сообщение отредактировано: juice -
                                                                            Цитата juice @
                                                                            Loviard ты опередил, я только хотел посмотреть во-что это скомпилится. Оказывается Dispose таки вроде как вызывается.
                                                                            :D :D :D Тайный заговор Микрософта раскрыт...
                                                                              Цитата Loviard @
                                                                              Более того, они как-то странно это сделали. Ты можешь отнаследовать класс от IDisposable, но компилер запретит тебе написать метод с названием Dispose.

                                                                              Это очевидно помоему, нельзя и рыбу есть и на велосипеде кататься :)
                                                                                Ну и само собой вполне корректно работает следующая ситуация, что сразу сводит на нет все безопасность:
                                                                                ExpandedWrap disabled
                                                                                  A^ f()
                                                                                  {
                                                                                    A a;
                                                                                    a.f();
                                                                                    return %a;
                                                                                  }
                                                                                   
                                                                                  void g()
                                                                                  {
                                                                                    A^ a = f();
                                                                                    a.f(); // !!! все вполне корректно :)
                                                                                  }


                                                                                Вот вам и область видимости переменной :D :D :D
                                                                                  Цитата Loviard @
                                                                                  Ну и само собой вполне корректно работает следующая ситуация, что сразу сводит на нет все безопасность:
                                                                                  ExpandedWrap disabled
                                                                                    A^ f()
                                                                                    {
                                                                                      A a;
                                                                                      a.f();
                                                                                      return %a;
                                                                                    }
                                                                                     
                                                                                    void g()
                                                                                    {
                                                                                      A^ a = f();
                                                                                      a.f(); // !!! все вполне корректно :)
                                                                                    }


                                                                                  Вот вам и область видимости переменной :D :D :D

                                                                                  Угу :) На сарае написано XXX, а там дрова лежат... вот так и тут по ходу выходит ... :)
                                                                                    Цитата Loviard @
                                                                                    еще раз повторяю свой вопрос.

                                                                                    Чего ты прикидываешься?
                                                                                    Несовместимы - это когда ты пишешь конструкцию ANSI C++, а она в режиме С++/CLI превращается в конструкцию С++/CLI - т.е. теряется возможность в одной программе использовать конструкции из обоих языков так, как они задумывались. Но ведь это не так, а значит - языки совместимы.

                                                                                    Цитата juice @
                                                                                    Цитата Loviard @
                                                                                    Ну и само собой вполне корректно работает следующая ситуация, что сразу сводит на нет все безопасность:
                                                                                    ExpandedWrap disabled
                                                                                      A^ f()
                                                                                      {
                                                                                        A a;
                                                                                        a.f();
                                                                                        return %a;
                                                                                      }
                                                                                       
                                                                                      void g()
                                                                                      {
                                                                                        A^ a = f();
                                                                                        a.f(); // !!! все вполне корректно :)
                                                                                      }


                                                                                    Вот вам и область видимости переменной :D :D :D

                                                                                    Угу :) На сарае написано XXX, а там дрова лежат... вот так и тут по ходу выходит ... :)

                                                                                    Да не, походу выходит, что управляемые программисты на ворнинги внимания обращают.. :blink:
                                                                                    Ну, тогда Бог с вами, возвращайте указатели на локальные автоматические объекты, если вам так хочется, а потом плюйтесь на язык.
                                                                                    Адью.
                                                                                    Сообщение отредактировано: Hryak -
                                                                                      Hryak, да мы не плюемся. Ты по моему не правильно толкуешь. Я например считаю C++/CLI вполне оптимальным выбором в некоторых ситуациях. Просто я думал ты волшебник и покажешь как объект SqlConnection поместить на стеке, а не в куче, а потом еще и коректно освободить память не вызывая Close. А ты просто описался видимо или думал о "стеке" рассмотренном выше.
                                                                                        Цитата juice @
                                                                                        Просто я думал ты волшебник и покажешь как объект SqlConnection поместить на стеке

                                                                                        Читаем внимательно в C++/CLI vs C# (сообщение #1945345)
                                                                                        Цитата Hryak @
                                                                                        И возня с using лаконичнее возможности размещения объектов "на стеке" в C++/CLI?

                                                                                        Кавычки видим? Я же их не случайно поставил, я прекрасно знаю, что такие объеты по-любому размещаются в управляемой куче, речь шла именно про семантику стека, а не про сам стек.

                                                                                        Добавлено
                                                                                        Цитата juice @
                                                                                        Я например считаю C++/CLI вполне оптимальным выбором в некоторых ситуациях.

                                                                                        Чтобы была ясность - я не считаю, что C++/CLI - оптимальный выбор во всех ситуациях. Я просто защищаю конкретную уникальную фичу этого языка, которую вы недооцениваете, имхо.
                                                                                          Цитата Hryak @
                                                                                          Чего ты прикидываешься?
                                                                                          Ты давай повежливее... Ты сам-то не прикидываешься? - ты понял что я имел в виду, более того, я это потом еще и объяснил подробно. В общем ты просто придираешься к словам.

                                                                                          Цитата Hryak @
                                                                                          Да не, походу выходит, что управляемые программисты на ворнинги внимания обращают..
                                                                                          Ну, тогда Бог с вами, возвращайте указатели на локальные автоматические объекты, если вам так хочется, а потом плюйтесь на язык.
                                                                                          Адью.
                                                                                          Ты чего кипятишься? Конечно я заметил варнинг, но это просто костыль компилятора. Потому-что код, который я привел вполне корректный. Объект располагается в управляемой куче, я увеличил количество ссылок на него, поэтому могу без задних мыслей его использовать в другом методе.

                                                                                          Цитата Hryak @
                                                                                          Чтобы была ясность - я не считаю, что C++/CLI - оптимальный выбор во всех ситуациях. Я просто защищаю конкретную уникальную фичу этого языка, которую вы недооцениваете, имхо.
                                                                                          Это не та фича, которая повлияла бы хоть на какое-то решение в его пользу. Фичи, ради которых, его действительно стоит использовать, я приводил выше...
                                                                                            Цитата Loviard @
                                                                                            Это не та фича, которая повлияла бы хоть на какое-то решение в его пользу.

                                                                                            Согласен.

                                                                                            По сабжу. ИМХО, вариант с auto_handle, выглядит естественней и действительно является классной фичей, равноценно-удобного аналога которого в шарпе дейтсвительно нет. Покрайней мере, на мой неискушенный взгляд, код в данном контексте получается ясный и явно демонстрирует намерения разработчика.
                                                                                              По поводу ASP.NET, сейчас для С++/CLI нет даже косвенной поддержки при разработке web приложений. Думаю это очень важная "фича".

                                                                                              P.S. Причина отсутствие в С++/СLI эквивалента partial классов.
                                                                                              Сообщение отредактировано: juice -
                                                                                                Пока, что неделю изучаю C++/CLI начинает уже нравится. По сравнению с C++ обычным это шаг вперед конечно. Куча полезных функций, куча полезных классов. Даже показалось, что объектно-ориентированность языка C++/CLI на голову выше, чем обычного С++. Помоему C++/CLI это вещь.

                                                                                                Но у меня родился вопрос, нестал отдельную тему создавать, спрошу тут.

                                                                                                Я чайник в VisualStudio - работаю с ней совсем недавно, до этого с другими IDE работал, со студией вообще не работал. Сейчас стоит VisualStudio2008 Team Suite, к самой студии уже привык, даже ни с чем другим работать теперь не хочется, после студии. :)

                                                                                                Но одно но, никак не могу привыкнуть к справочной системе MSDN, столько всего аж глаза разбегаются. :wacko:
                                                                                                Например мне нужно просто, чтобы был список классов, методов, полей описания их соответственно и т. д., и четкая структура классов .NET Framework, но никак не могу понять как например эту структуру в MSDN найти, чтобы эффективно работать с ней.

                                                                                                Как наиболее эффективно работать с MSDN? Поделитесь опытом.
                                                                                                Сообщение отредактировано: developer -
                                                                                                  Цитата developer @
                                                                                                  Например мне нужно просто, чтобы был список классов, методов, полей описания их соответственно и т. д., и четкая структура классов .NET Framework, но никак не могу понять как например эту структуру в MSDN найти

                                                                                                  В дереве слева выбираешь
                                                                                                  .NET Development - .NET Framework SDK - .NET Framework - .NET Framework Class Library и наслаждаешься всеми классами сгруппироваными по Namespase
                                                                                                  1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                                                  0 пользователей:


                                                                                                  Рейтинг@Mail.ru
                                                                                                  [ Script execution time: 0,1067 ]   [ 15 queries used ]   [ Generated: 8.11.25, 22:20 GMT ]