Как стать автором
Обновить

Комментарии 194

это своего рода «пасхальное яйцо») Эпизоды — напоминание Звездных войн.
2-ой эпизод пропустил, т.к. в фильме он назывался — «Атака клонов», что в контексте статьи не очень хорошо смотрелось бы)
Эпизод 2 пропустили. Вы необъективны и явно склоняете читателей в сторону C#.

Java более кросплатформенна, в статье вы сравниваете вроде бы языки, но потом переходите на CLR/JVM.

У нас же есть ещё F#, Scala, Mono, другие языки программирования, платформы, фреймворки, которые тоже имеют отношения к делу. Почему Вы их не упомянули?

Нужно использовать те языки и платформы, которые лучше подходят для реализации задач, стоящих перед разработчиком. А если человек знает и JVM, и .NET — это ему будет только плюс. А такие сравнения, как в статье, просто некорректны.
>Эпизод 2 пропустили

мой ответ чуть выше)

для объяснения отсутствия полной поддержки тех же generics, пришлось привести структуру CLR/JVM.

F#, Scala являются тяжеловесами совершенно другого уровня — чистые функциональные языки.

>Нужно использовать те языки и платформы, которые лучше подходят для реализации задач

абсолютно согласен, даже в статье об этом писал:
>>Для каждой задачи существует свой инструмент. Сравнивать C# и Ruby, например, не имеет смысла, т.к. их целевое предназначение совершенно разное, да и природа также. Однако именно C# и Java являются наиболее близкими по своей философии.
F#, Scala являются тяжеловесами совершенно другого уровня — чистые функциональные языки.
И давно F# стал чисто функциональным языком?
F# is a succinct, expressive and efficient functional and object-oriented language for .NET which helps you write simple code to solve complex problems.

research.microsoft.com/en-us/um/cambridge/projects/fsharp/
А ведь действительно
F# является мультипарадигменным языком. НО его основное предназначение — функциональное программирование!

ленивые вычисления — тому полное доказательство.
Lazy и в C# есть.

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

Было бы гораздо полезнее, если бы Вы написали статью в таком стиле:

[Класс задач] [Платформа / языки программирования для её решения] [Плюсы и минусы выбранной платформы для решения этого класса задач].

Тогда бы сравнение было бы более объективным. А сейчас оно перерастёт в холивар, где сторонники Microsoft / Oracle будут кричать, что их языки/платформа лучше. А лучшего в широком смысле слова просто нет.
>А лучшего в широком смысле слова просто нет.
Есть :-) Но это «лучшее» — чистый субъективизм :-) Лично для меня си-шарп в самом широком смысле — самое лучшее, что может быть. Просто потому, что я его знаю лучше других. Другие языки — обзорно или даже если профессионально, то давным давно. Если честно, я просто не могу жить без щарпных приблуд перечисленных в статье. Смутно ощущаю, что F# еще круче, но на чистую функциональщину мои мозги пока никак не хотят перестроиться. Поэтому «лучшее» существует!
Ясное дело, каждый выбирает лучшее для себя. Просто не стоит ограничивать себя каким-то одним мирком, будь то Oracle или Microsoft, а следует следить за трендами, ходить на конференции и знать, что предлагает та или иная технология, чтобы максимально эффективно решать стоящие перед разработчиком задачи.

Например, в нашей компании есть девушка, которая хорошо знает и C#, и F#, и в зависимости от того, что ей нужно сделать, она использует соответствующую парадигму программирования и язык, на котором она пишет.
Тут проблема есть освоения нужного языка. Допустим я точно знаю, что какую-то задачу можно эффективней решить с помощью такого-то языка. Но я знаю только его основы, и то «знаю» — громко сказано. И получается, что либо я буду много дольше писать эффективное в других отношениях решение, либо дольше решение сравнимое по эффективности с тем, что я написал бы на «родном» языке, лиюо быстро напишу на «родном», пускай оно и не столь эффективное будет. Какой путь предпочтительней? Не будет ли выбор более эффективного языка преждевременной оптимизацией?
Scala это не чисто функциональный язык, а вполне себе успешно совмещает ООП с функциональным подходом.
НЛО прилетело и опубликовало эту надпись здесь
>зачем?

можно чуть конкретно?)

>и как сделали красивые цветные штучки?
для этого в теги подзаголовков в начале вставлять данный тег .
все дело заключается в специальном символе ▌.
парсер съел :(
для этого в теги подзаголовков в начале вставлять данный тег
<font color="SandyBrown">▌</font>
НЛО прилетело и опубликовало эту надпись здесь
Хороший материал, пожалуй только отсутствие extension methods бросилось в глаза, без них и Linq, и asp.net mvc и многие другие выглядели бы не так красиво.

А почему корни постоянно ищут среди C/C++/Java? Андерс Хейлсберг, автор Delphi возглавляет группу по разработке C#, тащит туда из Delphi прообразы свойств, делегатов, зачатки мета-информации (от продвинутого RTTI до published-свойств), оставляет от C/C++/Java практически только синтаксис, но настоящего «папу» слава обходит :)
НЛО прилетело и опубликовало эту надпись здесь
tl;dr: C# — килотонна синтаксического сахара, Java — кроссплатформенность.

Кстати, анонимные классы в яве есть.
анонимные классы в C# представляют собой неизменяемые ссылочные типы, используемые лишь в методах.
анонимные классы в Java (они же inner class) используются обычно для переопределения методов базового класса.
В принципе в шарпе можно вернуть объект анонимного класса из метода, и получить доступ к его свойствам с помощью рефлексии. Или же воспользоваться типом dynamic
ответил чуть ниже)
inner и anonymous class — разные вещи
а в понимании товарища Oblitus — одинаковые )
Разные.

Java inner class:

public class DataStructure {
private class InnerEvenIterator {}
}

Java anon class:
new SomeInterface(){
public void function()
{}
}
Во-первых, как уже сказали ниже, анонимные и inner классы в Java — это совсем не одно и то же. Анонимные классы — это анонимная реализация некоторого интерфейса. Во-вторых, используются они для целой кучи вещей, в том числе вместо анонимных функций и событий. Если в CLR в последнее время ничего не понменялось, то делегаты и ивенты тоже реализованы через анонимные классы.
> анонимная реализация некоторого интерфейса

Необязательно интерфейса. Расширить обычный (или абстрактный) класс тоже можно анонимно.
Любой класс имеет некий интерфейс, так что можно считать, что противоречия нет.
>>Java — кроссплатформенность
“Saying Java is good because it works on all operating systems is like saying anal sex is good because it works on all genders" (с)
Anal sex. Connecting people.

Если кроссплатформенность требуется — ява таки да, лучше. По простой причине полной неприменимости шарпа. Моно не предлагать, его еще пилить и пилить.
Да уж, не легко наверное будет перенести эту модель на другую платформу — ведь придется уделять столько же времени и внимания )
А что в Mono ещё пилить?
В случае с явой я всегда знаю, что jar можно запустить на любой платформе с jre достаточно новой версии (можно поставить последнюю и не ошибиться). То, что работает под майкрософтовский рантайм, скорее всего не будет без напильника работать на mono. Плюс зоопарк версий дотнета.
Плюс зоопарк версий дотнета.

Целых две? Между которыми 10 лет
1.0, 1.1, 2.0, 3.0, 3.5, 4.0
И что? а у жабистов 1.2, 1.3, 1.4, 5, 6, 7
У жабистов достаточно иметь последнюю версию, и на ней гарантированно пойдет всё. Более того, байткод после компиляции имеет свойство идти на более ранних версиях, всё возможные проблемы исчерпываются наличием нужных стандартных библиотек. Дотнет тупо ставит весь этот зоопарк разом, что по моему мнению изжоп.
У жабистов достаточно иметь последнюю версию, и на ней гарантированно пойдет всё.

Да ладно! А что это:
www.oracle.com/technetwork/java/javase/compatibility-137541.html#incompatibilities
www.oracle.com/technetwork/java/javase/compatibility-137462.html
Что такое тогда?:) И это только 10 секндное гугление.

Дотнет тупо ставит весь этот зоопарк разом, что по моему мнению изжоп.

У вас неверные сведения. У дотнета специально ставятся рядом разные версии, чтобы не было неожиданностей, что что-то не работает в новой версии.
Проблема с обратной совместимостью. Но не с прямой. Запустить старый jar на новой jre можно. Для запуска старого шарпового кода нужен старый рантайм.

Это таки изжоп. На новых рантаймах джавы отлично работают старые джары. Причем со всеми плюшками новых оптимизаций.
Может и не изжоп. Я конечно не знаток, но разве отсутствие необходимости поддержки старых версий не открывает свободу маневра в реализации новых фич в новых версиях?
Пусть старые версии рантайма обслуживают старые приложения, а новые предоставляют преферанс и блудниц для новых приложений. Плюс при таком подходе добавление какой-то новой фичи не затронет уже проверенный и отлаженный старый функционал.
Да, конечному пользователю придется иметь несколько версий рантайма вместо одной, однако я считаю такой подход самым правильным.
На десктопе оправданный подход. В энтерпрайз среде — нет. Когда приложение должно расширяться и поддерживаться десятки лет. Причем не переписыванием на новую платформу, когда она выйдет. Конечно, многие стремятся к SOA, чтобы интегрировать гетерогенные системы, но и всякие WS-* не недавно появились. Тот же SOAP появился 1998.
Если чей-то код написан так, что его действительно необходимо, но при этом трудно и затратно подпилить под новую версию (трудно даже представить себе код, в котором больше 1 таких мест) то это говнокод, который ещё на стадии первой реализации забил на всякие солиды, архитектуру и т.п.

Не дописал, так вот: когда чот-то запускается, но часть не работает, вот это как раз тот самый «изжоп»
ну у jre тоже зоопарк, but who cares?

если вы скажете, что достаточно последнюю версию поставить, то я отвечу, что CLR тоже достаточно последний поставить (версия номер раз, потому как старый 3.5, который включает в себя все предыдущие, наверняка уже будет установлен (если не установлен, то это версия номер два).

в итоге получаем две версии фреймворка, которые может понадобиться установить, но скорее всего обыватель обойдется только самой последней.
А разве 3.5 включает 2.0?
хм. хороший вопрос. я просто понял, что ни разу его не ставил. Проблема видимо в том, что он принудительно ставится на XP то ли с SP2, то ли SP3, точно не помню. На Vista/7 дефолтно уже 3.5 установлен. На сервере 2008 в компонентах доставляется только 3.5, который все предыдущие версии в себе содержит. Вобщем, это уже лет 5 точно не является проблемой.
Проблему я вижу одну, но принципиальную: майкрософту приходится поддерживать три мажорных версии. И вечно этого делать никто не будет. Рано или поздно старые версии забрасывают. В случае с явой изначально нет нужды тянуть за собой мертвый груз. Там всегда доступна возможность использовать свежий рантайм.
А разве 3.5 включает 2.0?

Включает, у них один CLR, а вот 4.0 уже несовместим обратно
CLR легко запускает все старые приложения начиная с версии 2.0. не надо рассказывать, то что не знаете.
.NET 4 полностью перекрывает все остальные версии.
справедливости ради стоит отметить что различия-таки имеются (CLR2 и CLR4), например в обработке unmanaged exceptions-ов…
обработка SEH-исключений изменилась, но для обратной совместимости вносим следующие строчки в код:
<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true"/>
   </runtime>
</configuration>

и все работает по-старому)
.NET 3.5 состоит из CLR 2.0, версии библиотек 2.0 + новые для 3.0 + 3.5.
Просто «остроумная» шутка.
А в реальности разработчики на дажве без проблем пишут где хотят — в винде, в линуксе. Даже в одной команде. И оно-таки да — везде работает. А вот, с .NET у вас никакого выбора.
Пишу иногда на C# под Mono в Linux — о Windows-специфичных багах/глюках баг-репортов не получал.
Если Вам интересно посмотреть на C# и Java без субъективизма

А в итоге мы получили пост, расписывающий плюшки C# (весь 5-ый эпизод), и лишь пару слов о сравнении вначале (где в итоге все сводится к тому, как плохо в java реализованы обобщения), из-за чего получилось достаточно однобоко.

А ведь в по-настоящему ОО-языке everything is object.

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

Объективно обзор очень даже очень субъективный, в итоге получилось «как все хорошо в C#, и как все плохо в Java», автор имеет право на такую точку зрения, но это уже авторское мнение.
>>А в итоге мы получили пост, расписывающий плюшки C# (весь 5-ый эпизод), и лишь пару слов о сравнении вначале (где в итоге все сводится к тому, как плохо в java реализованы обобщения), из-за чего получилось достаточно однобоко.

а из всего перечисленного V эпизода разве что-либо присутствует в Java?

>>Справедливости ради, в том понимании этой фразы, о котором вы говорите (а именно буквальном), в C# также дела обстоят не так хорошо.

можно поподробнее?)

>>Объективно обзор очень даже очень субъективный, в итоге получилось «как все хорошо в C#, и как все плохо в Java», автор имеет право на такую точку зрения, но это уже авторское мнение.

лично я ни один раз не упомянул слова плохо или хорошо. выводы оставил читателям! если у Вас сложилось такое впечатление, то тогда это Ваше мнение, но не авторское!
>>а из всего перечисленного V эпизода разве что-либо присутствует в Java?

Описанные возможности анонимных классов, можно с успехом использовать и в java вики
Лямбда выражения полагаю вскоре появятся, здесь я признаю имеющееся преимущества, MS безусловно проще оперативно принимать решения по принятию нововведений, в java это всегда происходит очень натужно, кто-то всегда бывает с чем-то несогласен. Что касается, например, event-ов не считаю, что это вообще есть хорошо, программируя на C# всегда стараюсь их всячески избегать и использую стандартные паттерны, которые будут понятны на любом языке.

>>можно поподробнее?)

Можно) до нас это обсуждали ни один раз, если совсем коротко, то основная проблема связана с указателями, подробнее здесь или здесь.
Но все это относится к формальному подходу, о котором вы говорите, как по мне, так фраза everything is object относится к использованию принципов парадигмы ООП, и здесь java вполне себе соответствует этому, а вот c# со своими event-ами не всегда.

>>лично я ни один раз не упомянул слова плохо или хорошо

Ну, знаете ли, вовсе не обязательно говорить явно «хорошо» или «плохо», чтобы понять, что автор имеет в виду, если перечислять преимущество одного и подчеркивать недостатки другого, вывод напрашивается сам собой.
>>основная проблема связана с указателями…

я-то уже думал про что же будет идти речь ;)
тот же самый Липперт, пишет, что:
>>pointer types are treated like value types for the purposes of determining the storage requirements of their values

Но это уже другая тема для разговора)
Если сравнивать C# и Java (не Scala, а именно Java) то C# действительно мощнее и удобнее, это очевидно. В Java всего перечисленного в эпизоде V просто нет.
если вдруг такая необходимость появилась, то лучше всего использовать dynamic.
Насквозь субъективная статья, сравнивающая неизвестно что, и зачем, в непонятном базисе. Рекламу С# можно было сделать и покрасивее.
Минус за громкую претензию на объективность.
Плюсы Java для C# программистов:

1. Анонимные реализации. Это просто маст хев, такое уже есть в F#. Часто нужны миниатюрные реализации, а лепить целые классы скучно.
2. Импорт статических методов. Относительно редко нужная штука, но для DSL выглядит потрясающе.
3. Double brace syntax. Что-то типа with из бейсика. Реализация правда туповатая.
4. Неймспейс класа указывается одной строкой, нет ненужного лишнего таба когда пишеш клас
5. Крутые енумы. У них значение енума может иметь дополнительные поля. Например енум колор может содержать значения RGB по отдельности.
6. Ковариантности или инвариантность (я всегда это путаю) результатов метода. Технически каждый наследник может изменять возвращающее значение. Это даже статических методов касается. Вспомните WebRequest.Create(), он бы мог возвращать что надо.
7. Все методы виртуальные по умолчанию. Это двоякая фитча, я бы предпочел то что делает C#. Но то что мокать можна почти все что угодно, тоже вполне себе хорошо.

Какбудто бы все. Если что еще вспомню, напишу.
см. мой ответ чуть ниже)
1. Анонимные реализации — если имеется ввиду inner class, или же случай с Runnable и им подобным — то в C# существует намного лучшая реализация — делегаты.
3. Double brace syntax — блоки инициализации существуют в C# начиная с LINQ.
6. Ковариантность и контрвариантность существуют с C# 4
1. Случай Runnable скорее, по поводу делегатов, ну раскажите как делегаты круто выглядят когда надо два метода реализовать. Еще можете рассказать о «базовых/абстрактных делегатах» подумать. Когда надоест, поиграйтесь с F#, поглядите как эти штуки используют.
3. Расскажите тогда как метод вызвать в блоке инициализации.
6. Задачка WebRequest.Create возвращает WebRequest, его наследник HttpWebRequest.Create возвращает HttpWebRequest. Дерзайте.

Перед следующем ответом советую глубже вникать в суть.
>>ну раскажите как делегаты круто выглядят когда надо два метода реализовать

я, конечно, извиняюсь, но если надо «впихнуть» кода более чем на 3 строчки, а уж тем более в приводимом Вами случае, еще и 2 метода реализовать, небезызвестный Джеффри Рихтер, автор книги CLR via C#, советует как design consideration выделять данные конструкции в отдельные методы.

>>Еще можете рассказать о «базовых/абстрактных делегатах» подумать. Когда надоест, поиграйтесь с F#, поглядите как эти штуки используют.

как раз передо мной книга Chris Smith «Programming F#», O'Reilly. Обязательно расскажу чем там все закончилось!

>>Расскажите тогда как метод вызвать в блоке инициализации.

но зачем? Вы уже перешли в дебри дизайна реализаций кода. кому-то не нравится event вообще и использует паттерны вместо этого.
советую почитать чуть подробнее об инициализаторах.

6. я бы подумал об generics.
>> я, конечно, извиняюсь

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

>> но зачем?

Опять же попробуйте, вот пример DSL gist.github.com/300257, флуент ДСЛи вообще не смотрятся. реально же оно крутезно работает в паре с анонимными реализациями. Я думаю у меня под 50% класов, полноценными классами не становятся. А это и видимость, и захват переменных, и меньше кода, и локализированность кода, и закрытость реализации. Короче, совет тот же что и в первом случае. Собственно если у вас получится реально пописать на F# вы поймете.

>> я бы подумал об generics

Я привел пример. Можете попробовать реализовать его на дженериках. Create статический метод. Если честно 6й пункт это единственное на что мне никогда не надобилось ;).
>> Поговорим когда попробуете, реально разговор глухого со слепым.
Да, анонимные реализации это очень классно, szKarlen, попробуйте! Итераторы ими реализовывать одно удовольствие.

Кстати, уж коли заговорили про итераторы — в си-шарп есть классный yield, которого очень нехватает в Java при реализации итераторов.
C# обвиняли в копировании Джавы когда первый только появился. И не нужно никаких баек из недр MS — сходство было очевидное. Но. Так как с тех пор C# подвергся значительным изменениям (в отличии от Джавы), в настоящий момент говорить о копировании уже не приходится, однако не надо забывать что оно всё-таки было.

Спасибо за overview.
Не объективно. Фтопку
И где сравнение с Java? Я c# тоже могу так расхвалить.
Проработав 8 лет с C# и последние 3 года с Java могу сказать — самый большой epic fail Java и где Java действительно сильно проигрывает .Net, это generics. То, что на уровне JVM их нет это полный и бесповоротный капец. И ничего тут не спасает — ни scala, ни closure.

Но, в enterprise мире .Net нет. Его участь — это desktop и немного web.
А почему его нет? (Я не оспариваю, я в общем-то с Вами согласен, просто интересно послушать мнение).
Потому, что ничего для .Net enterprise уровеня как такого нет:
— нет application server уровня weblogic/jboss (хотя вру, есть COM+, но он был заброшен Microsoft)
— нет data/computation grid middleware gridgain/datasynapse (хотя вру, у DataSynapse только есть что-то, но там поддержка довольна примитивна и все равно java API этого грида гораздо более функциональный)
— нет распределенных кэшей coherence/terracota (Oracle Coherence опять таки позволяет хоть что то дать .Net приложениям, но через Coherence Extend, то есть, производительность будет на порядки хуже)
— JMS рулит как бридж в больших конторах (Tibco JMS тот же), MSMQ вообще никто не рассматривает.
— enterprise библиотек разного рода исторически все же больше для JVM, допустим того же аналога Akka для .Net нет.

Большие или почти все вытекает из за отсутствия cross platform у .Net, так как в больших конторах такой зоопарк hardware и os, начиная от solaris заканчивая тем же windows.

Да, у Java с cross platform то же не очень все хорошо, бывает что бажет JVM на разных платформах или тупо JVM уже не обновляется. Но полное отсутствие хоть какого то варианта запустить приложение на старом solaris'е — это просто гвоздь в гроб .Net

Между прочим Microsoft все прекрасно понимает, он никогда не сделает .Net cross platform и он даже не пытается захватить enterprise мир, делая ставку на desktop (WPF, silverlight) и только сейчас на web (ASP.MVC).

Так что из моей практики desktop front end это в 100% случаев это C# WPF приложения, backend это 99% Java.

.Net как проект, который был создан с учетом всех косяков JVM (classpath, поддержка разных языков программирования из коробки), с точки зрения программирования с моей точки зрения лучше, чем JVM. Просто надо не забывать о разделении применения.
Я, конечно, все понимаю, но:
— нет application server уровня weblogic/jboss (хотя вру, есть COM+, но он был заброшен Microsoft)
чем IIS + webfarm не угодил?
— нет распределенных кэшей coherence/terracota (Oracle Coherence опять таки позволяет хоть что то дать .Net приложениям, но через Coherence Extend, то есть, производительность будет на порядки хуже)

AppFabric Cache?
Есть IIS. Есть AppFabric, никто не мешает использовать memcached для кэша. Есть Alt.NET-овые аналоги MSMQ. Недостатка в Enterprise-библиотеках нет (может в Java их и больше — это не достоинство/недостаток какой-либо из технологий).

> «Так что из моей практики desktop front end это в 100% случаев это C# WPF приложения, backend это 99% Java.»

Именно что — из вашей практики. Из моей — примерно пополам. Причем, где есть веб — уклон в сторону .NET.
1. Как уже сказали выше — IIS с разными примочками.
2. SQL Server Hadoop?
3. Windows Server AppFabric Cache. Memcached отлично поддерживается. В облачной версии AppFabric Cache поддержан протокол memcached.
4. SQL Server ServiceBroker, NServiceBus.
5. Субъективно.

Думаю, ваше мнение было бы немножко не таким, если бы последние 3 года вы работали на .Net. Кстати, года 3 назад очень серьезно рассматривал вариант перехода на Java. Но решил подождать 4 фреймворк. И тут понеслось… Постепенно в МС начали выжимать стариков, веб просто шпарит семимильными шагами, меняется политика от закрытой экосистемы к открытой:

— МС пилили свой фреймворк для compute и тд — Dryad, но в 12 сиквеле мы получили Hadoop. У меня глаза на лоб полезли, когда увидел.

— Весь веб стэк отправили в опенсорс, да еще и в Git репозитории.

— Активно помогают портировать на Windows разные ништяки типа Redis, Node.js и тд.

— МС начал обращать внимание на фидбэк. Хотя бы недавний случай с Express студией.

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

А по поводу того, кто где распространен — очень серьезные товарищи пишут сразу и на .Net, и на Java. В зависимости от религиозных предпочтений одна из реализаций на боевых серверах, а другая на резервных. При возникновении проблем(технических, политических и тд.) происходит переключение. Однажды, к примеру, для продукта на Java пришлось писать антивирусный шлюза на .Net… Так что эти платформы гораздо ближе чем кажется на первый взгляд :) Джавистов уважаю, и считаю что сейчас все сводится (в 95%) к религиозным и политическим убеждениям, а так же просто привычки. Все imho.

Hadoop это все-таки java. А коннектор для big data не имеет только ленивый: см. бимеров, оракл и проч.
Hadoop запущенный на win остается java-приложением и к экосистеме .net не относится. В текущий момент он поддерживает win только как dev-платформу. То, что MS делает шаги в направлении запуска hadoop всего лишь означает, что она востребована.
Может для вас это в порядке вещей, но, к примеру, лет пять назад я бы не поверил, что такое возможно, и МС начнет смотреть на продукты других вендоров, а не только на то, что разработали сами. И как раз об этом я писал выше — внутри идет сдвиг от замкнутости к открытости. Redmond distortion field рушится ;-)
MS — комерсы, смотрят туда, где выгода. А big data — один из текущих трендов)
Все коммерсы=) Но раньше они замыкались в себе и пытались выстроить всю инфраструктуру сами. Сейчас начинают сотрудничать с другими. И Как раз это и нужно=)
Добавлю еще, что после того, как Web Division выкатил NuGet наблюдаю просто взрывной рост open source, и, что немаловажно, постепенный отказ от привязки версий различных фреймворков (Asp.Net MVC, EF) к релизам .Net. Это, имхо, была проблема.
Это как это его нет в энтерпрайзе? O_o Как раз там-то он есть, и еще как, нехреновый такой кусок энтерпрайза на дотнете. «Немного веб» — тоже сильно сказано, ASP.NET намного популярнее Java Server Pages. Не говоря уже о популярности SharePoint — энтерпрайзного портального ASP.NET-приложения.
Сравнили кислое с теплым: Веб фреймворк для .NET с технологией для генерации динамических страниц на Java.

По поводу Sharepoint прокомментировать ничего не могу.
Ну я не в курсе просто насчет деталей JSP/JSF. Тем не менее — отнюдь не теплое с мягким — все-таки и то, и другое — веб-технологии.
JSF не единственный из Java Веб-фреймворков. И на мой взгляд далеко не самый лучший, хотя я с ним почти что не знаком. Из того, с чем я работал, и что мне в принципе пришлось по душе — Struts2. Spring MVC наверное тоже сюда можно добавить, хотя я с ним почти что не знаком. Во всяком случае, несколько REST сервисов, что мне удалось увидеть, написанных на нем выглядели вполне симпатично.
Для REST-сервисов сейчас принято использовать аннотации JAX-RS, которым глубоко не важно, что Вы используете: Resteasy, Jersey, CXF или ещё что-либо. Struts, Spring, Seam и прочее даёт инфраструктуру (те же tx, security, persistence и т. д.).
«Но, в enterprise мире .Net нет.»
Видимо мне он там мерещится, хотя мы его внедряли раз так несколько.
Kotlin должен спасти — там, по крайней мере, избавились от erasure (думаю, что с помощью какого-нить хака, но не суть).
Если Вам интересно посмотреть на C# и Java без субъективизма...

Опечатка: «Без» на «С» замените.
Java развивается слегка несколько консервативно, но это компенсируется семейством новых языков, которые набирают обороты на JVM'e: Scala, Groovy etc.
Мало, что субъективно, так ещё и не верно во многих местах.

> Таким образом, вся политика безопасности типов разрушается моментально.

С какого это перепугу она разрушается? В Haskell типы в рантайме тоже не сохраняются, однако более типобезопасный язык вы вряд ли найдёте.

> Количество инструкций у обеих платформ примерно одинаковое. Сравнивая список команд байт-кода Java и CIL, видно, что 206 у Java, и 232 — CIL, однако не забываем, что у Java многие команды просто повторяют функционал друг друга.

А вот в наших автомобилях вдвое больше педалей, правда наши автомобили круче?!
Важно не то, сколько, важно то, какие важные инструкции присутствуют в байткоде.

> Также исчезает потребность в boxing/unboxing.

И каким боком тут boxing/unboxing? Преобразование к структурам позволяет работать с ними как со значениями, а не пихать в память, нагружая сборщик мусора. Дженерики здесь воообще нипричём.

> Также generics в C# позволяют использовать value types (int, float и т.д.)

А ничего, что, например, int в C# — это System.Int32, т.е. структура? В итоге List в C# — это по сути то же, что и List в Java.

> Эпизод V: Возможности C#

Как уже говорили, вы сравниваете не те языки. Java изначально делала упор на простоту, плюс из-за проблем у Sun и сообщества долго не могла (и всё ещё не может) включить в язык многие плюшки. А сравните с авторской Scala, у которой этих проблем нет — нормальные замыкания с поддержкой каррирования вместо убогих делегатов C#, pattern matching, traits и companion objects, actors и многое другое, о чём в C# ещё только начинают мечтать. Заметьте, всё это принципиально новые возможности, в отличие, например, от лямбда-функций, событий и т.д., являющиеся не более, чем синтаксическим сахаром.
>>И каким боком тут boxing/unboxing?

а это тогда что? или джавовский List<T> не скатывается к List<Object>? 


String x = (String) list.get(0);


>>В итоге List в C# — это по сути то же, что и List в Java.

точно???
т.е. Эпизод III не читали?

>>Как уже говорили, вы сравниваете не те языки

Хм… отвечу уже Вам.
Оба языка со C-подобным синтаксисом. Оба языка прикладного уровня. Управляемые. Со сборщиком мусора (причем GC — generational). Оба используют JIT, bytecode. Используются при разработке корпоративного софта, на них разрабатывают дескпотные, мобильные и веб-приложения, могут запускаться на Win, *nix (C# благодаря mono). Так и кто должен был быть в сравнении тогда?
> а это тогда что? или джавовский List не скатывается к List
Дженерики съели текст :) Отформатировал как смог.

> а это тогда что? или джавовский
List< T >
не скатывается к
List< Object >
?
String x = (String) list.get(0);

Это приведение типов, как бе, к упаковке структур не имеет никакого отношения.

>>В итоге List в C# — это по сути то же, что и List в Java.
> точно???
> т.е. Эпизод III не читали?

Скобки съелись, должно было быть:
List< int >
в C# и

 List< Integer >
в Java. Другими словами, в C# вы всё равно не оперируете примитивами, вы оперируете специальными структурами.

> Оба языка со C-подобным синтаксисом.

Схожесть синтаксиса — отличный аргумент. Когда уже люди начнут смотреть на семантику языка, а не на то, круглые скобочки или фигурные.

> Оба языка прикладного уровня. Управляемые. Со сборщиком мусора (причем GC — generational). Оба используют JIT, bytecode. Используются при разработке корпоративного софта, на них разрабатывают дескпотные, мобильные и веб-приложения, могут запускаться на Win, *nix (C# благодаря mono).

Всё то же самое могу сказать про Common Lisp. Сравним?
Вы пытаетесь сравнить кита и слона — кто из них сильнее? Вы говорите: «кит сильнее, потому что он больше», но как только кит оказывается на суше, он становится беспомощным. Если вас интересует только масса сравниваемых животных (количество крутых фич в языке), то сравнивайте хотя бы белого кита и кашалота (C# и Scala).

> и сколько разработчиков на Scala?

А какая разница? Язык доказал свою пригодность для систем совершенно разного рода и сформировал вокруг себя довольно сильное сообщество, где всегда можно найти ответы на интересующие вопросы. Вам от языка нужно ещё что-то?

> Scala требует некоторого изменения в мышлении.

Вы не поверите, любой язык требует некоторого изменения в мышлении. Более того, даже измнение проекта может потянуть за собой изменение мышления.
>>Это приведение типов, как бе, к упаковке структур не имеет никакого отношения.

про структуры было чуть далее)

если произошло недоразумение, то
при List<T> в C# не происходит ни упаковки примитивов, ни приведения типов при операциях
.

>>Вам от языка нужно ещё что-то?
ок)

>>Вы не поверите, любой язык требует некоторого изменения в мышлении
проверено на себе — лямбда-выражения оказали влияние :)
> если произошло недоразумение, то
> при List<T> в C# не происходит ни упаковки примитивов, ни приведения типов при операциях

А что такое приведение типов? Для приведения типа A к более «узкому» типу B рантайму нужно проверить, безопасно ли такое приведение, т.е. сравнить типы. И чем это отличается от динамической проверки типов в C#? Да ничем, по большому счёту, просто происходят они в разное время, а общий оверхед примерно одинаковый (и при этом очень небольшой).
В Java для приведения к более «узкому» типу необходимо явное приведение на этапе компиляции.

В случае type erasure проверка происходит на раннем этапе, при компиляции. Основные проблемы с generic-типами в этом случае при смешивании legacy кода (написанного под 1.4 или более раннюю jvm). Если я правильно помню, в JLS3 описаны причины такого решения при проектировании generic'ов. Такой вариант позволяет старому коду прозрачно взаимодействовать с новым (при условии, что старый код аккуратно работает с обновленными частями JRE).

То есть, если в legacy-код передать List<String>, а он запихает туда значение иного типа, то ошибка произойдет в рантайме. И это лучше, чем невозможность взаимодействовать со старым кодом вообще. Но приведение List к List<String> является небезопасной операцией, поэтому требует явного приведения типов и генерирует предпреждение, если не поставить аннотацию @SuppressWarnings(«unchecked»).

Бытует распространенное мнение, что generic'ов в рантайме нет. Это не так. Reflection позволяет вытащить некоторую информацию. Примеры можно смотреть в CDI-библиотеках.
>>А сравните с авторской Scala

и сколько разработчиков на Scala? Scala требует некоторого изменения в мышлении.
У вас неверные представления о Scala — как раз на ней можно писать так, как писали на Java (правда, внезапно можно получить снижение производительности и некоторые другие не очень очевидные вещи), постепенно переходя на Scala-way.
> «вы сравниваете не те языки»
Как ни крути, Java и C# — как раз те языки, которые вполне себе можно сравнивать. Корректность/некорректность и объективность конкретного сравнения — другой вопрос.
Опять же, речь шла о наборе фич языка. И сравнивать C#, который тянет в себя всё подряд, с консервативной Java нет смысла — у них идеология в плане новых фич разная. А вот со Scala — в самый раз.
А причём тут идеология, когда сравнивается набор фич? Набор фич — это моментальный срез, история и прогнозы развития какое значение имеют?
Как я уже говорил, чтобы не сравнивать кита и слона. Java и C# имеют примерно одинаковую внутреннюю структуру (промежуточный код, модель памяти) — ок. Оба языка делают сильный упор на объектно-ориентированное программирование — ок. Но цели у них всё равно разные: Java — это кроссплатформенность (ну, по большей части), enterprise, сообщество, в том числе open-source; C# — это только Mircosoft, декстоп, проприетарные приложения. Какой тогда смысл подсчитывать фишечки вещей из разных категорий? Вы же не станете подсчитывать, насколько в лексусе больше магнитол, чем в танке?
«декстоп, проприетарные приложения» — лет 6 назад я бы с вами согласился. Сейчас .Net очень комфортно чувствует себя на сервере. Да и open source проекты в полный рост. Тот же WCF на сервере мне импонирует гораздо больше чем то, что представлено на Java стеке и вполне хорошо уживается на серверах вместе с Java based продуктами. Просто не надо смотреть на .Net свысока, считая что его удел это только десктоп. Эти времена уже давно прошли. В следующий раз, когда будете проводить платеж через интернет банк, платежный терминал или какие-нибудь интернет деньги, представьте, что возможно в 30% случаев это будут обрабатывать сервера на Windows Server.

Не для холивара, а для ознакомительных целей могу рекомендовать почитать:
Comparing .NET and IBM WebSphere 7 Application Server Performance

Ну смотрите. Во-первых, продукты MS — это всегда платно и чаще всего дороже: аренда серверов на Linux стоит дешевле, при желании можно собрать хороший устойчивый и совершенно бесплатный стек Java-based технологий; для .NET бесплатно или за дёшево можно получить только самый простой стек — сколько раз я удивлялся товарищам дотнетчикам, ругавшимся из-за того, что опять нужно покупать очередной компонент или тратить 3 недели на разработку своего. Про такие вещи как SQL Server я уже не говорю.

Возможно из-за платности многих компонент хуже развивается и направление open-source. Если посмотреть на breakdown языков программирования на GitHub (правая колонка), то можно заметить, что репозиториев на Java целых 115869 штук, а вот на C# в 4 раза меньше — всего 27197. Думаю, статистика по другим хостингам тоже будет говорить в сторону Java.

Выбор технологий. На C# для веба вы наверняка выберете ASP.NET MVC. Википедия говорит, что есть пара других вариантов, но честно говоря о большинстве из них я слышу первый раз. Да и к тому же добрая половина из них ещё и проприетарная. Для Java же есть Spring, Struts, Richfaces, Seam, GWT, Play!.. И каждые пару лет появляется что-нибудь новое. Добавьте к этому фреймворки для JVM-based языков, такие как уникальный Lift для Scala или Compojure/Noir для Clojure (про фреймворки для F# или Nemerle Википедия почему-то молчит). И всё это, о чудо, бесплатно и открыто. Заметьте, я не говорю, что такой разнобой лучше — лично я уже давно точу зуб и на Java-сообщество, и на open-source в его теперяшнем виде — я просто подчёркиваю разницу. Поэтому я и говорю, что заявлять, что C# круче Java, потому что в нём есть ивенты, которые нужны в основном для десктопа, на который Java особо и не претендует — это как-то некорректно.
Если мы рассматриваем энтерпрайз, то это наверное IT бюджеты более 1 mln USD. И, приведенный мной документ как раз рассматривает еще и ценовой аспект.
Если в целом смотреть, то тот же Windows 2008 Web Server стоит, если мне память не изменяет, около 9000 р. Ну, право, это не серьезно(кстати в Azure 10 сайтов бесплатно:-)).
А жалуются, по моему опыту в основном из-за того, что не осведомлены о существующих альтернативах. Это, кстати, пока еще достаточно часто встречается у .Net разработчиков (сужу по собеседованиям). И, кстати, весь стек можно собрать по сути за те же 9000 р., так как взяв тот же NHibernate, вы не привязаны к бд. При еще большем желании — mono :).

Я и не говорю, что Java лучше или хуже С#(.Net). По моему опыту, они сейчас на равных. Есть и сильные и слабые стороны. Open source на платформе .Net достаточно туго развивался до выхода Asp.Net MVC, который, по сути, стал локомотивом для всей платформы в этом направлении. У Java здесь есть определенная фора. Плюс не стоит забывать, что до определенного времени, MS игнорировали open source. Честно, завидовал когда мои team mates использовали Hibernate, а мне приходилось сидеть на голом ADO.NET :-). Для .Net тоже есть спринг Spring Framework.Net.

По части языков это отдельная тема, так как по моему мнению, частично причиной их появления послужило весьма неспешное развитие Java как языка. Тот же C# развивается гораздо более быстрыми темпами, в результате потребность не такая большая, но при этом — List of CLI languages.
Это если брать энтерпрайз или по крайней мере большие проекты (и, кстати, Java уровня enterprise тоже далеко не бесплатная), однако тот же опен сорс, академические разработки, проекты «для своих» как правило пишутся энтузиастами, и вкладывать в эти проекты деньги из своего кармана им тоже не сильно хочется. Кроме вопроса платности стоит также вопрос открытости стека технологий. Например, такие мастадонты опен сорса как Solr, Hadoop и Nutch внутри используют линуксовские системные утилиты или проектируются с расчётом на Unix-like системы (поставить Nutch под Windows, например, это тот ещё аттракцион).

В мире .NET всегда есть один вендор, который ставит музыку, и все остальные должны под неё плясать. В мире Java единого вендора нет: не хотите использовать Oracle Java — OpenJDK (и куча других реализаций) всегда открыты для вас; не хотите пользоваться IntelliJ IDEA — Eclipse, NetBeans и дальше по списку; вам надоел Spring — попробуйте Play! и т.д. В итоге приходится думать, как угодить всем — не поверите, но многие адепты Java активно протистуют против включения в язык таких вещей как модули и лямбда-функции. То же самое с платформами: хотите включить новую фичу в JVM, а ну посмотрите, можно ли будет её реализовать на всех поддерживаемых платформах, и сколько это будет стоить. В случае с C# обо всех таких вещах, как правило, не беспокоятся, поэтому и могут свободно эксперементировать с языком и платформой. Отсюда и куча дополнительных фич, и поэтому если сравнивать набор фич C# и JVM-языком, то лучше брать Scala.
МС кстати работает в направлении портируемости софта зацепленного на Unix-like системы. Тот же LibUV. Не все гладко но это уже прогресс. Ну на Mono достаточно шустро уезжают все фичи, кроме специфических кусков которые применимы только к Windows и к спеке языка это никак не относится. Плюс сейчас народ пилит OWIN и тд. Все это, имхо, в силу того. что поздно начали адаптироваться к open source. А для энтузиастов есть экспресс версии. Если ходить на разные конференции — можно запросто получить это бесплатно. Плюс для начинающих компаний есть шикарный BizSpark.
Не хотите использовать Visual Studio — используйте Mono Development, не хотите использовать .NET — используйте Mono, не хотите использовать Windows — используйте Linux/MacOS (с Mono). Единственное существенное ограничение, имхо, нельзя использовать именно .NET на не Windows. Ну и будут проблемы, если вы захотите создать кроссплатформенное приложение, с нативным L&F для Windows без использования .NET.
Забавный, но в принципе, ожидаемый выбор конфигураций тестовых стендов. Я еще понимаю (ибо не в курсе архитектурных особенностей POWER6), что 8 ядер Power6 как-то можно сравнить с кластером из 4х 4-ядерных ксеонов, но то что суммарный объем памяти в кластере 128ГБ против 32ГБ в системе от IBM да и различия в структуре сетевой подсистемы (4 адаптера на одной системе против 4 отдельных серверов с 2-мя адаптерами). Словом, очень неочевидная претензия на объективное сравнение.
Там интересна цена=) Ведь, по сути, в таких решениях важен уже не выбор ЯП, а цена, отношения с вендором и тд.
Ну не знаю, как по мне, то сравнивать быстродействие систем имеет смысл только на сравнимых по производительности вычислительных комплексах. а иначе так можна купить Ford Model T и какую нибудь новую модель Porsche, по стоимости они ведь сравнимы. В чем смысл, Брат? ©
Но я буду подсчитывать где магнитол больше — в Лексусе или Феррари, хотя в них разные цели заложены производителем, но у меня цель комфортно ехать, а не соответствовать ЦА.

Выбирая язык для кроссплатформенного приложения я рассмотрю серьезно 4 варианта (не ограничиваясь обзорами и холиварами, а попытавшись написать прототипы с ключевыми фичами приложения, попробовав по паре фреймворков): C++, C#, Java и Python. C++ и Python первые кандидаты на вылет (хотя, конечно, от приложения зависит).
Серьёзно? Ваши заказчики или руководство ждут, пока Вы сделаете 4...8 прототипов? Чего только на свете не бывает…
Не ждут :( Говорят «Пиши уж на PHP»… И пишу, например, электронный документооборот.
Вы назвали конкретную цель сравнения — комфортно ехать. В отрыве от этой цели сравнение теряет смысл. Например, зачем в Java вводить специальную конструкцию для событий? Кто и где её будет использовать? В вебе и без событий неплохо, а для декстопа в Java всё равно не хватает нормальной базы, и ивенты ситуацию не исправят.
>>А сравните с авторской Scala

Это не имеет смысла в свете того, что последняя изо всех сил старается начать компилиться в CLR.
Речь вроде бы шла о сравнении фич двух языков, на какой именно платформе эти языки крутятся в данном конкретном случае значения не имеет. А то, что Scala портируют на CLR говорит только о её популярности и востребованности.
Ну, если сравнивать авторские языки, то Scala надо сравнивать с авторским Nemerle.
А в каком он, кстати, сейчас состоянии? Использует его кто-нибудь в продакшене?
В очень хорошем состоянии. Много кто использует в продакшене, из крупных твиттер, линкедин… ну и помельче конторы активно юзают.
Я про Nemerle.
Если кому будет интересно, мы в девклубе однажды решили устроить «баттл» — .NET против Java. В тот раз победил .NET, хотя, конечно, это ещё ничего не значит. Видео доступно тут.
Мне, как Java developer'у было бы интересно сравнение производительности и стабильности двух аналогичных по функциональности веб-приложений под хорошей такой нагрузкой на примерно одинаковом железе, только Java чур под *nix подобной системой.

Я бы всерьез задумался о смене платформы если бы увидел, что Java обосралась по полной программе по бОльшей части пунктов.

В Java не все гладко. Но где оно гладко? А синтаксический сахар, на почве которого товарищ пытается склонить в мелкомягкий лагерь, это конечно же клево, но без этого спокойно и без проблем можно жить.
Java будет жить ещё долго, особенно консервативная энтерпрайз среда. И переход с одной платформы может быть неоправдан (в смысле затрат времени, например). Особенно, если у Вас большой опыт на одной из них.
С# как язык мог бы иметь бОльший успех, если бы имел порт под JVM. Но так как когда мы говорим С# мы подразумеваем платформу .NET, то это не вариант.

Куда более реальным выглядит проростание в энтерпрайзы со временем таких языков как Scala/Groovy (что там еще под JVM выйдет), нежели смена платформы.
Это да. Недаром развиваются вещи типа JRuby, Kotlin. JetBrains пытается внедрить MPS, например.
Как раз web-приложения достаточно кроссплатформенны благодаря Mono.
это не java. дети малые. Это dalvik, который сливает в т.ч. и oracle java. Причины разные. Иногда мобайл оптимизации, иногда просто не зрелось. Иногда патенты.
Есть такой плагин интересный для Eclipse — lambda4jdt, который позволяет в IDE визуально сворачивать любой анонимный класс с один методом в лямбда-выражение.
IntelliJ IDEA делает это автоматически (начиная с 10 версии, если не ошибаюсь).
В IntelliJ IDEA такое поведение по умолчанию присутствует в случае Runnable/Callable. Да и на самом деле это не такая уж большая проблема.
Не только. С любыми анонимными реалзациями интерфейсов.
Вероятно. Не обращал внимания
> и даже не является holy war, не стоит даже вопрос: «кто круче»

Ха-ха.
Жаль что статья не рассказывает что-же есть в java чего нет в C#.
После прочтения вступления было ожидание что сейчас расскажут где лучше C# а для чего больше подходит Java или описание отличительных особенностей.
К сожалению ожидания не оправдались.
Хотя про generics было интересно.
Что-то я не понял — причем здесь Java?

И — да, особенно понравилось:

> instance.Value = «new string value»;
> //будет вызван метод instance_Changing

Наверное, C# не для меня. Не люблю сюрпризы в коде )
Зачем нужна Java или C#, если есть C++?
Ну, это вы толсто.

Языки сильно разные. Плюсы это только глубокий бэкэнд. А эти наоборот.
На java тоже довольно много бэкендовых вещей пишут: lucene, hadoop/hdfs/hbase. Тот же hypertable (с++) пока сильно не дотягивает до hdfs.
Ну, признаюсь, с Java я знаком только как с языком, но не эко-системой.
Но просто представляю хорошо, где плюсы исопльзуются и примерно, где Java.
С оптимизацией в java становится получше. Так что в некоторых областях она даже обгоняет плюсы. В частности засчёт того, что не гонится за оптимизацией всего. Тот же jit работает на тех функциях, которые вызываются чаще. И измерения производятся непрерывно при работе jvm.

Например, тот же lucene — это поисковые индексы. Штука довольно низкоуровневая (куча битовых операций, математики), высокопроизводительный поиск, чувствительная к io. Развивается, имеет большое сообщество. А стоит глянуть в сторону плюсов — глухо.

Так что в некоторой области java, c++ и с конкурентоспособны. В том числе, в области бэкендов. Особенно приятен управляемый код, когда надо мигрировать код и данные между различными нодами. Скорость разработки выше и сложность поддержки кода ниже на java чем на плюсах. И вместо дорогостоящего написания кода на c++ выбирают большее количество ресурсов. А при некоторых условиях на java горизонтальное масштабирование становится довольно дешевым.
Синтаксический сахар идет лесом. Скажи ка лучше (я реально не интересовался) в C# memory model есть?
Она должна относится к CLR, а не языку. Также, как JMM.
Упссс. А мужики то не знают?
А как писать параллельные программы без MM?
Скажите это в частности Боэму, благодаря которому в С++0x11 таки появилась MM.
А кто-то действительно может утверждать, что Java как язык в чем-то удобнее С#? Минус у C# только один, но он для многих краеугольный: винда. Те, кто не готов с нею связываться, просто вынуждены писать на Java…
Как язык — нет. Ванильная Java консервативнее и строже, нововведениями обрастает неохотно, синтаксическим сахаром не балует. Впрочем, желающим сахара есть много различных подсластителей вроде Groovy, Scala и так далее. И если сравнивать с C# их — всё становится куда сложнее.
Ну это вы зря так. У java mainstream спектр использования — это веб-сервисы и корпоративные сайты. Возможности большие, но спектр использования — нет.
У шарпа тоже спектр использования свой — десктопные приложения и, возможно в небольшой степени (статистикой не владею), веб-сайты.

Разные сферы использования, разные задачи — разные иструменты. А винда тут ни при чем. Заказчика интересует конечная стоимость и стоимость поддержки, и я уверен, в случае крупных корпоративных задач, стоимость винды в этом списке будет незначительной.
Не понимаю откуда этот миф, что C# это больше десктоп.
За 6 лет практики, я знал только одного коллегу, у которого есть товаришь, друг которого писал десктоп приложения.
Загляните на тотже Elance, oDesk 95% это ASP в той или иной форме.
Я знаю, что в Штатах, в частности, ASP.NET очень широко используется. Просто я не в курсе мировой статистики использования.
Статистика немножко не корректна. В ней под ASP.NET понимаются WebForms.
Тот же MVC потихоньку набирает обороты.
trends.builtwith.com/framework/ASP.NET-MVC
Хотя так вообще немного странная статистика, так как в «Technologies with similar web coverage to ASP.NET MVC» числятся Visual Studio, Perl, Python И Sharepoint 0_o.
Десктоп обсуждать смысла нет — если пишем windows-приложение нет оснований писать не на С#, если не-windows, то наоборот — писать на C# смысла нет.

Все-таки спор скорее про серверную часть корпоративной трехзвенки (с клиентом-браузером или другим толстым или тонким клиентом). И тут сервер на windows или linux — думаю для многих первоочередной вопрос. Потом уже выбор языка. Вопрос конечно не в цене, а вообще в выборе платформы. Я бы при всей любви к C# не стал завязываться на виндовые сервера.
если не-windows, то наоборот — писать на C# смысла нет.

Ежедневно запускаю приложение на C# (плеер) под Линуком — никаких проблем не вижу.
C# кросплатформенность? Нет, не слышал
НЛО прилетело и опубликовало эту надпись здесь
По моему сравнивать C# и Java смысла нет. Да, они похожи, да оба используют байт-код. Но в каждом их различии есть и плюсы, и минусы. Большинство «багов» в Java оставлены для обратной совместимости.
1. Байт код. Ну да, в C# полиморфный, в Java нет. И что? Вы не упомянули такую особенность: при компиляции байт-кода в .NET создается кешированный исполняемый файл. То есть при следующем запуске программы, компиляции байт кода не будет, а просто возьмется файл из кеша. В теории это должно ускорить запуск приложения. В Java такого нет. Тут при каждом запуске происходит компиляция. Однако, есть возможность модифицировать существующие методы (не добавляя новых типов/методов) и не прерывая приложение перекомпилировать исходный код. Не знаю, где это применяется, кроме как в отладке, но это круто :)
2. Генерики. О, да, в .NET это сделано круто, не поспоришь. Тут есть только один минус (да и минус то он с натягом) — так как разные генерики являются разными типами (например List и List — разные типы), то они все грузятся в кучу. (List и List — 2 записи в куче). Чем больше вы используете генериков, тем больше они отжирают памяти и тем больше процессора надо GC для обработки. А в Java все генерики — лишь видимость, в байт код идут
Да, спасибо, я в курсе. Несколько лет пишу на C# и первый год на Java. Я имел ввиду, что в Java я могу полностью переписать метод и не останавливать даже дебаг при этом.
>>Не знаю, где это применяется, кроме как в отладке, но это круто :)
в .NET тоже самое — прямо в дебаггере изменяем код + continue

>>Чем больше вы используете генериков, тем больше они отжирают памяти и тем больше процессора надо GC для обработки

знаете, особенностью generics в .NET является code-sharing, т.е. для
List<Object> и List<string>будут сгенерированы одинаковые x86-инструкции
. для ознакомления можно почитать здесь.
> в .NET тоже самое — прямо в дебаггере изменяем код + continue
А это не инкрементальная компиляция с подменой класса в рантайме?
именно она)
Думаю товарищ tym32167 имел ввиду её же. Но это вопрос к компилятору и IDE. Что JVM, что CLR умеют подменять класс в рантайме, насколько мне известно.
>> в .NET тоже самое — прямо в дебаггере изменяем код + continue
Этого не знал. Просто небыло надобности. Очень интересно, спасибо :)

>> знаете, особенностью generics в .NET является code-sharing
Я имел ввиду, что в кучу загрузятся 2 типа. Про инструкции ничего не говорил. Также сказал, что минусом это с натягом можно назвать
JIT-компиляция происходит не при запуске, а после сбора статистики. Сначала работает интерпретатор байткода.

Про модификацию и генерацию байткода — применений довольно много: AOP, генерация прокси для классов (не интерфейсов, см. cglib), генерация кода сериализации/десериализации в рантайме (kryo), миграция кода на другие jvm (gridgain).
'Object'. Вы указали минусы этого. А плюсы? никому не надо переписывать свои JVMы чтобы начинать поддерживать генерики! Если .NET Framework производит MS (ну, и Mono ещё), то разработчиков JVM по моему гораздо больше, и заставлять их всех переписывать свой код только для поддержки сахара не круто.
3. Типы. Конечно, в Java есть примитивные типы, которые не наследованы от Object. А в C# они наследованы и всё такое. Но вот только в .NET с примитивными типами не всегда следует обращаться, как с Object. Простой пример — финализатор. Допустим, мы проектируем структуру и вешаем на Finalize какое то важное действие. Теперь поразмыслим. Когда вызывается финализатор? когда объект удаляется GC. Какие объекты удаляет GC? он удаляет объекты в куче. А струкура у нас значимый тип и хранится в стеке. Как вывод, в структуре финализатор может быть не вызван никогда, хотя он наследуется от Object.
4. Исходные коды. Не знаю, как вам, а мне нравится в Java то, что я в любой момент могу поглядеть, как устроен, например, тип String. Весь его исходный код. Не работает метод из JDK? а погляди его исходник, что он конкретно делает? И для этого практически не надо делать телодвижений. А в .NET не всегда это получится. Да, можно взять рефлектор, залезть в библиотеки, декомпилировать и лицезреть. Но это не одно и то же, что полный доступ к исходным кодам.
5. Документирование. Комментарии. Сравните описание коллекции в .NET и Java. Я считаю, что в Java всё расписано намного подробней и понятней.

Да, в .NET много плюшек и всё такое, но он развивается с тем прицелом, чтобы быть удобным для разработчиков. Java развивается, чтобы удовлетворять не только разработчиков, но и производителей JVMов. Практически любые косяки, которые можно перечислить в Java, оставлены или не сделаны или сделаны именно тем образом по соображениям обратной совместимости. Поэтому, давайте не будем спорить, кто круче, везде есть свои плюсы и минусы.
Но это такие не весь исходный код, а часть базового кода одной из версий фреймворка… За ссылку спасибо :)
Можно еще тут посмотреть:.NET Framework Libraries Часть, как уже писал выше в одном из постов, доступна на CodePlex.
>> и заставлять их всех переписывать свой код только для поддержки сахара не круто.

синтаксический сахар — не зависит он возможностей VM. LINQ — и все остальное можно скомпилировать и для .NET 2.0.
что мешает разработчикам сделать по-умнее свой компилятор? generics же сделали?

>>Какие объекты удаляет GC? он удаляет объекты в куче. Как вывод, в структуре финализатор может быть не вызван никогда, хотя он наследуется от Object.

в .NET разница между кучей и стеком весьма тонкая. CLR сама может поставить value type в кучу, если жизненный цикл объекта недетерминирован.

>>4. Исходные коды
про библиотечные коды Вам уже ответили.
что касается исходников самой CLR, GC, JIT — то пожалуйста — Shared Source Common Language Infrastructure 2.0. Это своего рода исследовательский проект (в нем отсутствует, например, code-sharing, но зато он послужил основой для Mono.
>> синтаксический сахар — не зависит он возможностей VM. LINQ — и все остальное можно скомпилировать и для .NET 2.0.
Генерики для .NET 1.0 скомпилировать тоже можно?

>> что мешает разработчикам сделать по-умнее свой компилятор? generics же сделали?
ну дак они и делают (генерики ж сделали :))

>> в .NET разница между кучей и стеком весьма тонкая. CLR сама может поставить value type в кучу, если жизненный цикл объекта недетерминирован.
Ну круто, это как то противоречит тому, что я написал?

>> про библиотечные коды Вам уже ответили.
Спасибо, вот это интересно, я погляжу

У меня такое ощущение, что мне хотят доказать, что C# круче. Я же просто хочу сказать, что не нужно сравнивать. У каждого из этих языков своё назначение.
>>Генерики для .NET 1.0 скомпилировать тоже можно?
см. Эпизод V

>>У меня такое ощущение, что мне хотят доказать, что C# круче. Я же просто хочу сказать, что не нужно сравнивать. У каждого из этих языков своё назначение.

ну нет) просто предназначение, IMO, более чем близкое. однако после некоторых доводов джавистов в комментах, складывается ощущение, что C# надо было сравнивать со Scala.
>> см. Эпизод V
Перечитал, но ответа не увидел. Ткните плиз пальцем :)
:D я имел ввиду все, что из Эпизода V (св-ва, события, делегаты, LINQ и т.д.)
* (например List[int] и List[String] — разные типы)
Интересно, когда музыканты собираются вместе попить пива, они тоже обсуждают, что лучше, трамбон или кларнет?
Мы профессионалы, языки — инструменты, надо будет — любой выучим и к любому приспособимся. А носиться с языком как со священной коровой, бред какой-то.
Это лишь с одной стороны.
Мне очень нравится Java своей экосистемой, однако мне так порой не хватает struct и хотя бы делегат.
Простите, не вижу Эпизод II

Так и задумано? Или он будет потом?
Спасибо! Не могу понять, почему не увидел раньше. Но спасибо вам за терпение.
Пожалуйста ;)
Насчет Generics
1) То, что в Java информация не доступна в рантайме — это миф. Например, погуглите Super type tokens
2) А в C# в дженериках есть маски и ограничения?

Вообще, отличная статья — мне как Java разработчику было очень интересно почитать. Но с претензией на объективное сравнение — это вы зря — объективностью тут не пахнет :) Надо было так и назвать статью «Плюшки С#, о которых Java разработчики могли не знать» — в таком ключе читать, действительно, интересно.
2) насчет wildcards — благодаря ковариантности обобщенных интерфейсов мы можем записать так:

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Circle>();

        DrawShapes(list); // ошибка отсутствует
    }

    static void DrawShapes(IEnumerable<Shape> shapes)
    {
        foreach (var shape in shapes)
        {
            shape.Draw();
        }
    }
}

public abstract class Shape
{
    public abstract void Draw();
}

public class Circle : Shape
{
    public override void Draw()
    {
        //do something
    }
}


либо же просто указываем конкретные допустимые типы:

static void DrawShapes<T>(List<T> shapes) where T : Shape
{
    foreach (var shape in shapes)
    {
        shape.Draw();
    }
}
Ну и да, тоже хотелось бы услышать про Memory Model в C#
это отдельная большая тема, которой нужно посвятить еще одну статью)
Мне было бы очень интересно!
А то всё про JMM, JMM…
OK) тогда попробую объединить данную тему еще и с многопоточностью!
В java так и не появилась обработка переполнения или неверной операции с числами. В одном проекте с интенсивными расчетами задолбался искать, где ошибка. А вешать assert после каждой арифметической операции довольно муторно.

В c# есть инструкция checked или галочка на проект, чтобы проверять арифметику.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории