Задача


Вот бы, разрабатывая программу на одном языке, сразу получать исходники на других языках программирования… Я пишу на C# .NET, но в последнее время всё больше требуется интегрироваться с Java. Одно из решений — оформление web-сервисов для взаимодействия, но не то это, не то. Вроде и существуют конвертеры C# в Java, но эксперимент показал, что для реального проекта они (те, что удалось попробовать) не работают, хотя на «hello world» отрабатывают отлично. Переписать с нуля на Java весь проект нереально — он активно разрабатывается более 6 лет (Pullenti — обработка естественного языка), да и на C# он нужен. Пришлось мобилизоваться и в прошлом году написать этот конвертер, а в этом году и конвертер C# в Python.

Опыт создания конвертера C# в Java


Итак, на входе проекты (solution) Visual Studio, нужно получить классы на Java. Разумеется, не все типы проектов возможно поддержать, но тип «Class Library» и «Console Application» — вполне. Проекты не должны использовать никакие графические библиотеки типа System.Drawing, никакие Windows-возможности или DllImport, а для используемых библиотек должны существовать аналоги в Java. К счастью, для используемых мной возможностей такие аналоги нашлись (работа с XML, архивы GZip и др.). От некоторых несущественных деталей пришлось отказаться, немного подправив алгоритмы. На уровне языка C# и Java близки, но Java чуть беднее — вот что в нём отсутствует:

  • property { get; set; } — приходится работать с функциями;
  • struct — структуры отсутствуют, поэтому сначала я их моделировал просто классами Java, но затем переписал алгоритм, отказавшись от них полностью;
  • delegate — отсутствуют, но моделируются интерфейсом с одной функцией;
  • event — моделируется массивом ArrayList из элементов класса, реализующего интерфейс соответствующего delegate;
  • out и ref аргументы у методов — моделируется классами с одним полем Value;
  • internal — этот модификатор вообще не имеет смысла в Java, так как отсутствует понятие сборки, поэтому просто заменяется на public;
  • new Class() { присваивания } — приходится создавать статическую функцию, в которую выносить эти присваивания;
  • enum — если в C# возможны побитовые операции с его элементами, то в Java это запрещено, и конвертеру приходится enum преобразовывать в классы Java;

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

Если нужно было исключить из кода C# некоторый фрагмент или оформить его немного по-другому для Java, то использовались директивы препроцессора #if JAVA… #else… #endif.
Вот так, постепенно дополняя конвертер новыми функциями и подправляя исходный код на C#, удалось прийти к тому, что генерируемые на Java более чем 1500 юнит-тестов стали отрабатывать правильно, как и их прототипы на C#.

Сравнение скорости работы .NET и Java


Теперь самое интересное. Есть трудоёмкий алгоритм (в основном работа со строками), и абсолютно идентичные его реализации на C# и Java. Как «апологет» .NET, я всегда сомневался в эффективности Java. Но оказался неправ — C# всего на 15-20% быстрее Java (запускал из Eclipse под Windows), а не в несколько раз, как ожидалось. А какова ситуация с Python? Читайте дальше.

Опыт создания конвертера C# в Python


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

Что в Python отсутствует или неудобно:

  • for(init, cond, incr) — в полноценном виде отсутствует, есть некоторые частные случаи с range, но в основном приходится моделировать через while;
  • switch — отсутствует, моделируется if-then-else-ами;
  • interface — отсутствует, но это просто класс с пустыми методами;

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

Сравнение скорости работы .NET и Python


Многие жалуются на низкую скорость работы Python, но насколько она низка? И низка ли? Пришло время сравнить на том же алгоритме, что и для Java (точнее, на тех же юнит-тестах). Готовы? Итак, Python работает в 30 раз медленнее, чем .NET (запускал в Eclipse под PyDev).

Причина, думаю, в следующем. В Python отсутствуют простые типы как ValueType (насколько я понял), и даже обычные числа — это полноценные объекты (фактически как boxing в .NET). И элемент строки — это не символ, а тоже строка из одного символа! То есть string[i] — это не char, а как бы string.Substring(i, 1) в .NET.

Технология кросс-языковой разработки


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

  • исходники на Java (конвертер);
  • исходники на Python (конвертер);
  • проекты на .NET Core (отдельные csproj-файлы, но исходники те же);
  • проекты на .NET Framework 2.0 (конвертер, и такое нужно для одного заказчика);

Поделюсь одной полезнейшей возможностью Visual Studio, которой почему-то мало пользуются даже профессиональные разработчики C#, к моему глубокому удивлению. И которая отсутствует в средствах разработки, скажем, для Java. А именно — возможность изменять код и перемещать текущую позицию прямо в ходе выполнения, причём состояние всех переменных сохраняется и можно продолжить выполнение с учётом внесённых изменений. Это кардинальным образом облегчает отладку, особенно когда для воспроизведения нужной ситуации требуется некоторое время. Например, я включаю режим, при котором Visual Studio приостанавливает программу в месте возникновения Exception (вернее, я этот режим никогда не отключаю), запускаю длительную обработку, а через сколько-то минут или часов возникает эта ситуация, чаще всего NullReference. Я исправляю код, и вместо того, чтобы перезапускать программу, перемещаю точку выполнения на нужный оператор назад и запускаю выполнение дальше. Да и вообще частенько я прямо в ходе выполнения реализую сложные алгоритмы в нужных местах. Помнится, когда делал систему биржевой торговли, то это на порядок облегчало жизнь в условиях трудоёмкой процедуры инициализации и выхода на нужную алгоритмическую ветвь. В Visual Studio эта возможность достигается за счёт тесной интеграции IDE и компилятора — они могут себе такое позволить. Но вернёмся к технологии.

Ограничения очевидны — только библиотеки и консольные приложения. Почти нереальны конечные приложения с пользовательским GUI или Web-приложения. Да и при разработке библиотек приходится придерживаться ограничений, накладываемых требованием универсальности. От чего-то придётся отказаться, что-то переписать, но результат стоит затраченных усилий!

Комментарии (60)


  1. Terranz
    05.05.2018 21:41

    Хорошая статья, спасибо.
    А по поводу изменения кода в памяти и перемещения указателя: можно просто поставить брейкпоинт и в нём уже запустить Evaluation окно с отдельным кодом внутри, который подцепит все переменные и так далее.


  1. linuxover
    05.05.2018 21:54

    > Python работает в 30 раз медленнее, чем .NET.

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

    а вообще интересно на код конвертера бы посмотреть :)


    1. SirEdvin
      05.05.2018 22:24

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

      А тут нужны cython + numpy и сверху еще numba было бы неплохо. А чистый python сильно проигрывает :(

      Ну или pypy, как предлагают ниже, но numba должна быть круче.


    1. Antervis
      06.05.2018 13:35

      основные реализации python — не полноценные вм, как у java/c#, а обычные не оптимизирующие интерпретаторы. python хорош для использования библиотек (особенно написанных на c/c++), но не для их написания. И уж тем более не для арифметических задач.


    1. Trixon
      06.05.2018 15:02

      www.researchgate.net/figure/Speed-comparison-of-the-Neighbor-Joining-program-Speed-comparison-of-the_fig2_5600272

      Вы даже не представляете, как ошибаетесь.
      Python везде выдаёт самый худший результат по производительности.


    1. KonstantinSmith Автор
      06.05.2018 17:02

      Да что на него смотреть — код как код. А вот сгенерированные коды на Java и Python можно посмотреть на сайте (www.pullenti.ru/DownloadPage.aspx). А первая задача была — это чтобы сам генератор, который на .NET, перевёл сам себя в Java и также работал.


  1. Northborn
    05.05.2018 22:04

    Попробуйте использовать PyPy вместо CPython, он с JIT компиляцией. На данный момент поддерживает Python до 3.5 включительно. (Легко) можно получить прирост в скорости до x10. Код переписывать не надо.


    1. KonstantinSmith Автор
      06.05.2018 17:27

      Извиняюсь, забыл указать в статье, что Python запускал в Eclipse под PyDev (подправил статью). Может, в какой другой среде это будет побыстрее.


  1. Antervis
    05.05.2018 23:23

    а не логичнее ли наладить interoperability компонентов, написанных на разных языках?

    Но оказался неправ — C# всего на 15-20% быстрее Java (запускал из Eclipse под Windows), а не в несколько раз, как ожидалось

    вы всерьез сравниваете производительность оригинального C# кода и автогенерированного, использующего оболочки и эмулирующего C#-концепции Java-кода?


    1. mspain
      06.05.2018 11:07
      -4

      Не проще просто писать на java, которая в отличие от кое-чего запускается на нормальной серверной ОС? Виндовс-сервер это оксюморон. В тепличных условиях пусть будет +15% (лениво проверять), а через полгода шындовш уже пучит и таращит, через год минус 50% производительности


      1. perfectdaemon
        06.05.2018 11:16
        +7

        Стыдно в 2018 поливать грязью .net-платформу и не знать про .net core


        1. mspain
          06.05.2018 11:38
          -4

          Стыдно должно быть сравнивать зрелые платформы SE и EE с этим. Когда от например RedHat появится решение и саппорт, тогда и поговорим о core


          1. perfectdaemon
            06.05.2018 12:26
            +4

            Как определяется зрелость платформ? Год, пять или десять лет?

            На RHEL есть поддержка .net core: пруф.


            1. mspain
              06.05.2018 12:57
              -4

              Если мерять годами, то язык brainfuck (создан в начале 90х) всегда будет более зрелым решением, чем net core. Шах и мат, микрософт. :) не вижу смысла продолжать тему сравнения зрелости net и java


        1. vsapronov
          06.05.2018 18:14
          +4

          perfectdaemon mspain
          Попробую примирить. mspain — вы неправы в 2018 году, dotnet core очень годится для продакшена на RedHat. Сам пишу на нем и на Scala. Кроме того, в 2018 году Java — убогий язык и писать на нем изначально, плохая мысль.
          perfectdaemon с товарищем надо полегче. Дело в том, что некомпетентный майкрософт много лет игнорировал линукс, заявлял что open source — это рак, при этом не имея вообще ничего на сервере. Хуже того, армия майкрософтовских фанбоев поддерживала всю эту галимотью. Тот факт, что теперь у мс и его сообщества есть хейтеры — это нормальная реакция. Теперь надо делать добро и адекватные шаги ровно столько же времени, сколько они подсиради опен сорсу вообще и линуксу в частности, т.е. Ещё лет 10. Репутация — такая штука…


          1. mspain
            07.05.2018 10:21

            По вашему если что-то сделать опенсорсным, оно мгновенно и обязательно превращается в конфету? У МС есть что-то подобное java EE? Если нет, то им еще лет 10 надо сидеть молча и пилить, пилить.


            1. IvanNochnoy
              07.05.2018 13:10

              Есть. И подобное и бесподобное.


          1. mspain
            07.05.2018 10:27

            У меня, кстати, к МС претензии ко всем продуктам от кривого гипервизора до отвратительного Word-а (жизнь заставляет иногда в нем верстать). Так что опенсорсность core ничего не меняет


    1. mspain
      06.05.2018 11:27

      Ещё очевидно, что программы не берут данные из воздуха и не складывают в воздух. А известно как в винде работают субд. Какая тормозная ntfs и тд и тп. В итоге скорость ПРОГРАММНОГО КОМПЛЕКСА под net обгоняет java только при очень непрямых руках и в get the facts


      1. alexs0ff
        06.05.2018 12:55
        +1

        винде работают субд

        Причем тут винда и субд. Например, сейчас есть в продакшене система на .netFramework, которая ходит на Oracle, который в свою очередь установлен на линуксе.
        Плюс майкрософт сделала порт своего SQL Server на линукс. поэтому ограничений в .net, почти нет (ну кроме нормальных кроcплатформенных ГУИ, но я бы тут взял или QT или Electron)


        1. mspain
          06.05.2018 15:37

          Клиент на dotnet, бизнес-логика на могучем plsqlчике, третий уровень не завезли? Я тоже видел тонны подобного крапа от подрядчиков нашей конторы. К обсуждаемой теме performance оно каким боком? :)


    1. KonstantinSmith Автор
      06.05.2018 17:08

      вы всерьез сравниваете производительность оригинального C# кода и автогенерированного, использующего оболочки и эмулирующего C#-концепции Java-кода

      Ну да, тем более, что обёрток там не так уж много, и для несущественных для производительности объектов. А так всё идентично — классы, методы, циклы, ветвления, массивы и пр. стандартные конструкции. Хотя, может, каких-либо «блох» и можно отловить. В принципе, генерируемый код Java выложен на pullenti.ru/DownloadPage.aspx, если Вы там обнаружите навскидку какие неэффективности — буду признателен!


  1. RolexStrider
    05.05.2018 23:46

    Еше во времена .NET 1.0 сами Microsoft такое пробовали (конвертер из Java в C#, ЕМНИП было в VS.NET 2003). Не взлетело, и уже в VS 2005 убрали. А наоборот — полагаю что даже сложнее будет.


    1. SanSYS
      06.05.2018 17:39

      Наверное имеется в виду J#
      https://ru.m.wikipedia.org/wiki/Visual_J_Sharp


      "Заявленной целью разработки Visual J# было облегчение перехода разработчиков с платформы Java на платформу .NET Framework. Однако эта цель достигнута не была" =)


  1. a-tk
    05.05.2018 23:52

    Редактирование кода на лету имеет ряд ограничений: нельзя добавлять/удалять классы/внутренности классов, нельзя править генераторы и прочие методы, которые разворачиваются в машины состояний, нельзя править методы, содержащие лямбды, и многое другое. Остаётся процентов 20-30 тривиальных случаев.


    1. KonstantinSmith Автор
      06.05.2018 16:58

      Зависит от проекта. У меня таких случаев как раз 80-90% (обработка естественного языка), и весьма нетривиальных.


  1. a-tk
    05.05.2018 23:53

    Код на производительность тестировался как? Сконвертированный сравнивался с исходником, или нормально переписывался с учётом особенностей целевого языка? В первом случае любой код будет медленнее исходного языка.


    1. KonstantinSmith Автор
      06.05.2018 18:48

      Нормально переписать нет никакой возможности — проекту около 7 лет, там сложные алгоритмы лингвистической обработки, морфологический анализ, выделение именованных сущностей (NER). Повторю, что использовались только «стандартные» языковые конструкции, эквивалентные в .NET и Java (от экзотики я избавился в ходе работы над конвертером). Не думаю, что можно как-то существенно оптимизировать код Java (см. результат генерации pullenti.ru/DownloadPage.aspx?file=PullentiJava.zip). Может, есть какие тонкие настройки оптимизации в самой среде Eclipse. Например, когда я начинал запускать в NetBeans, то там скорость почему-то была медленнее раза в 2. Скажем, в Visual Studio в режиме Debug скорость меньше на такие же 15-20%, чем в Release. Хорошо бы ещё проверить под Unix, но нет под рукой. Но в целом можно утверждать, что скорость примерно одинакова.


      1. a-tk
        06.05.2018 22:29

        То есть в сущности это не сравнение производительности, а просто проверка того, насколько просела производительность после автоматической миграции.


  1. kemsky
    06.05.2018 00:33

    Так как есть JPython, то может быть даже достаточно перегонять только в питон, для джавы написать отдельно интерфейс.


  1. TimReset
    06.05.2018 00:53

    В Java тоже есть редактирование кода на лету, правда работает оно не из коробки — нужно запускать на пропатченном jvm и с java agent'ом. (Для dcevm актуально). Это всё не сложно сделать. Хотя перенос, как вы выразились, «текущей позиции», всё же не поддерживается, насколько я знаю.
    dcevm.github.io бесплатная
    zeroturnaround.com/software/jrebel платная, очень платная
    Я пользовался обеими и для большинства случаев первого хватит. Насколько я помню, основное отличие в поддерживаемых framework'ах — т.к. при изменении кода иногда нужно учитывать работающие в приложении framework'и и дёрнуть их методы (например, добавили поле которое испольуется в DI и его нужно инициализировать, вот dcevm и jrebel посмотрять, что у вас за DI framework используется и применят его)
    Но по опыту — если такая фигня начинает быть важна, значит что то не то в архитектуре приложения — поидее всю логику работы нужно уметь востанавливать по логам и быстро воспроизводить в тестах. По крайне мере мне эти штуки пригодились только на таких проектах — тестов нет, запускается очень долго, и поэтому приходиться в run time код писать :-)
    P.S. давно статью по dcevm писал, может пригодиться, habr.com/post/236075


  1. impwx
    06.05.2018 12:53
    -1

    В Python отсутствуют простые типы как ValueType (насколько я понял), и даже обычные числа — это полноценные объекты (фактически как boxing в .NET).
    Это ерунда. В дотнете значимые и примитивные типы — это не одно и то же. Например, string — примитивный, но ссылочный, а Decimal — значимый, но не примитивный.

    Каким образом вы определяли, что обычные числа используются как объекты? Вы смотрели ассемблерный код, генерируемый JIT? Я не знаток питона, но практически уверен, что проблема производительности не в нем, а в том, что ваш генератор выдает неэффективный код.


    1. alexs0ff
      06.05.2018 13:15
      +1

      Например, string — примитивный

      Да, ладно!
      var isPrimitive = "Hello World!".GetType().IsPrimitive;
      Console.WriteLine(isPrimitive);
      >>out -> false
      


      1. impwx
        06.05.2018 18:16

        С точки зрения CLR тип string вполне себе примитивный: для него есть отдельный опкод, его можно использовать в аргументах атрибутов и в константах. А свойство просто проверяет текущий тип на вхождение в некий список. Если пытаться сформулировать правило, по которому здесь определяется примитивность типа, то оно получается длинным и неуклюжим. Поэтому я подозреваю, что на самом деле причина историческая: так реализовали в первой версии, а потом не стали менять для сохранения обратной совместимости.


        1. alexs0ff
          06.05.2018 21:40

          Если пытаться сформулировать правило, по которому здесь определяется примитивность типа, то оно получается длинным и неуклюжим

          Зачем формулировать правило, которого нет в спецификации языка C#?
          Даже Джон Скит, не называет string примитивным типом и полностью доверяет type.Isprimitive

          I wouldn't personally call dynamic, decimal, object or string primitive types. I'd use Type.IsPrimitive for the canonical source there.


          Источник
          stackoverflow.com/a/47589777


          1. impwx
            06.05.2018 22:51

            Во-первых, в спецификации языка C# определения примитивности и не может быть, потому что это более низкоуровневая вещь, относящаяся ко всему CLR.

            Во-вторых, именно отсутствие нормального определения побуждает к попытке сформулировать свое. В ECMA-335 я такого не нашел, всё так или иначе упирается в это самое свойство IsPrimitive, а рекурсивное определение, даже подтвержденное личным мнением Джона Скита, на мой взгляд бесполезно.

            Для себя я определяю «примитивный» тип как нечто базовое, что CLR особым образом использует и на что полагается. Под такое определение строка подходит — в формате метаданных CLI есть даже отдельная секция для хранения строк.

            Какое определение больше нравится — решать вам. Но если вы знаете ситуацию, в котором текущая реализация IsPrimitive имела бы осмысленную практическую пользу — пожалуйста, поделитесь.


            1. alexs0ff
              07.05.2018 08:21

              в спецификации языка C# определения примитивности и не может быть

              Ага, а вот в спецификации VB.NET есть секция 7.3
              The primitive types are identified through keywords, which are aliases for predefined types in the System namespace.

              Там же, кстати, к примитивным типам относят и Decimal, Date

              Для себя я определяю «примитивный» тип как нечто базовое,

              Так и писали бы в первоначальном сообщении ИМХО — вопросов бы не было.


  1. Restorer
    06.05.2018 13:07
    +2

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

    Haxe (https://haxe.org/), не?


    1. KonstantinSmith Автор
      06.05.2018 17:39

      Да, наверное, неточно выразился. Правильнее было бы так:
      Вот бы, разрабатывая программу на одном моём любимом языке C#, сразу получать исходники на других распространённых языках программирования Java и Python


  1. alexs0ff
    06.05.2018 13:14

    DEL


  1. Goodkat
    06.05.2018 13:26
    +1

    Был же вроде проект наоборот, конвертировали Андроид с Явы на Сишарп.


  1. AdAbsurdum
    06.05.2018 17:10

    А что будет с NuGet-пакетами?


    1. KonstantinSmith Автор
      06.05.2018 17:14

      Если нет аналога в Java — то никак не конвертируется. Или использовать исходники пакета, если есть, для конвертации и их в Java. Увы, есть ограничения… Например, связанные с использованием GUI или некоторых Windows-возможностей (какой-нибудь реестр). Но в рамках, скажем, функционала .NET Core этих ограничений будет меньше.


  1. devpreview
    06.05.2018 17:11

    Для таких задач можно попробовать GraalVM.

    C# нет, но есть Truffle и возможность имплементить свой язык.


  1. Dreamer_other
    06.05.2018 17:15

    А как именно вы делали конвертацию? Этого в статье не хватает.


    1. KonstantinSmith Автор
      06.05.2018 17:22

      Сначала попробовал конвертеры C# в Java из Интернета (парочку), но они выдавали некомпилируемый результат с кучей ошибок. Может, есть какие платные получше, но денег разбираться нет. Писал сам, на это ушло около 3-х месяцев, зато теперь конвертирует то, что нужно, и как нужно сразу рабочий код. Задача была добиться того, чтобы результат вообще не нужно было бы вручную как-либо корректировать. Поскольку такие генерации идут периодически при доработках исходного проекта на C#. А в этом году за месяц доделал конвертер для получения Python. Но это так — экзотика, так как реальных проектов у меня для Python нет.


  1. Konstontin
    06.05.2018 17:40
    +2

    Может быть язык Haxe — это то, что вам нужно


    1. KonstantinSmith Автор
      06.05.2018 17:41

      Да, наверное, неточно выразился в начале статьи. Правильнее было бы так:
      Вот бы, разрабатывая программу на одном моём любимом языке C#, сразу получать исходники на других распространённых языках программирования Java и Python


  1. SanSYS
    06.05.2018 17:46

    Месье знает толк в извращениях...


    Если верно понял, Пайтон был по фану
    А не хотите во что-нибудь поэкзотичнее конвертнуть?
    Например Go или Rust))


    1. KonstantinSmith Автор
      06.05.2018 18:26

      «Штирлиц был извращенец, поэтому во Вращенцах ему был установлен памятник.» Могу и в Go, если там будет не памятник, а хотя бы небольшой бюстик…


  1. erzi
    06.05.2018 18:33

    «new Class() { присваивания }»

    в Java — new Class() {{ присваивания }}


    1. KonstantinSmith Автор
      06.05.2018 18:36

      Надо же, не знал! Спасибо, оказывается, так можно — подправлю конвертер.


      1. turbanoff
        06.05.2018 18:50

        Это не то же самое. Этот вариант создаёт анонимный класс.
        Не стоит править — просядет производительность.


      1. ExplosiveZ
        06.05.2018 18:57

        Так делать нельзя. Это уже будет не `Class`, а некий другой, анонимный `Class`.
        // Я буду обновлять комментарии перед отправкой своего.


        1. erzi
          07.05.2018 06:43

          Что тут анонимного, это блок инициализации?


  1. Dj_Art
    06.05.2018 18:36
    +1

    Похвально. Но, есть такая штука как IKVM.NET. Разработка относительно недавно прекратилась, однако, позволяет запускать почти любой JVM байткод на .NET, и при том умеет не только интерпретировать, но и компилировать. Так, кстати говоря, можно из Java в C# перегонять код, при помощи декомпилятора. И даже Interop с Java есть, можно создать jar-обертку для.NET кода и использовать ее при разработке на Java, с одним ограничением — код должен исполняться в IKVM.


  1. AnarchyMob
    06.05.2018 18:36

    Лучше конечно конвертировать на уровне байт кода, а не исходного кода. Я встречал на хабре несколько таких проектов, например CIL2Java, был еще dot42 и множество других.


    1. turbanoff
      06.05.2018 18:50

      Чем лучше?


  1. KvanTTT
    06.05.2018 22:12

    Интересно, мы в Swiftify занимаемся конвертером Objective-C в Swift, и я могу сказать что это непростая задача.


    А какие вы использовали библиотеки для парсинга и обработки C#, Java и Python?


  1. ruslanfedoseenko
    07.05.2018 10:52

    По поводу Java<->.NET есть такой «диназавр» IKVM.NET. Умеет бинарники в jar и наоборот. Но я так понял вам важно иметь именно исходники.