C#, как язык, поинтересней джавы. И многие вещи сделаны правильней.
Чем интереснее, отсутствием дизайна? Я абсолютно не понимаю почему из него не чистили косяки при отсутствии обратной совместимости. Больше всего поразила null-фобия.
Джава лет 10 топталась на месте.
Крокодилы тоже много лет не менялись, в своей нише вполне успешны. Чего именно тебе в джаве не хватало все эти 10 лет?
Мне нравится, вот только свободная реализация в виде Mono - говно. И Gtk# как говно в квадрате.
Хотел тут поделку на моно писать, т.к. опыта C# больше чем плюсового, но в итоге ушел на Qt. В Gtk# даже стандартные контролы с экспшнами слетают на ровном месте. Это нельзя назвать разработкой нормальной.
Вот если M$ сделают свои WinForms кроссплатформенными, тогда можно было бы что-то думать. Но MS конечно никогда ничего подобного делать не будет, а всякие Gtk# - неюзабельное школьное поделие.
Поэтому скорость работы в мильён раз существеннее. Но эту тему ты ловко обошёл.
Часто бывает, что если за неделю не разработал, то можно уже ничего вообще не делать.
Память растет, количество ядер увеличивается и заработать кучку денег _сегодня_, намного важнее сэкономленных 500Мб памяти за счет лишнего месяца разработки.
Чем интереснее, отсутствием дизайна? Я абсолютно не понимаю почему из него не чистили косяки при отсутствии обратной совместимости. Больше всего поразила null-фобия.
Нормальные generics. LINQ. Async/await. Properties. Extension Methods. var. value types. Это только то, что я знаю, а я C# очень издалека палочкой тыкал.
А какие именно косяки не чистили? Что за null-фобия?
Крокодилы тоже много лет не менялись, в своей нише вполне успешны. Чего именно тебе в джаве не хватало все эти 10 лет?
Вот если M$ сделают свои WinForms кроссплатформенными, тогда можно было бы что-то думать. Но MS конечно никогда ничего подобного делать не будет, а всякие Gtk# - неюзабельное школьное поделие.
WinForms это же обёртка надо WinAPI, как они их сделают кроссплатформенными? Над вайном что-ли, или предлагаешь им WinAPI портировать под линукс? :)
Да пусть и над Gtk, но нормальные контролы. Не вылетающие, хорошо настраиваемые, принимающие .NET типы вроде DataTable и DataSet. Без этого толку от .NET'а не особо много(для меня по крайней мере).
А WinAPI на линуксе(кросплатформенно в смысле) это был бы номер.
Не знаю для чего они с шарпе, но в джаве дженерики совершенно для другого. Применения шарповским я в своё время так и не придумал.
LINQ
Так и не понял нафига оно надо
Что за null-фобия?
Ну первая версия совсем не содержала null. Потом туда прикрутили nullable дженерики. Мне было очень весело когда с одной стороны у меня были int? а с другой int (они не кастяться ни туда ни обратно). Потом стандартные типы постоянно выкидывают всякие эксепшены при попытке работать с null. Например стандартные мапы выкидывали key not found и key is null (или как то так). Т.е. вместо того что б просто вернуть null из мапы если я передал null в качестве ключа, который получил из какого-нить метода, мне приходилось заворачивать всё в if'ы. Сложилось стойкое впечатление что делали так, чтоб NPE никогда не вылетел, в результате наплодили кучу маразма.
Не знаю для чего они с шарпе, но в джаве дженерики совершенно для другого. Применения шарповским я в своё время так и не придумал.
Для другого это для чего? new T() даже нельзя написать. Приходится Class<T> прокидывать доп-параметром только из-за того, что генерики убогие.
LINQ
Так и не понял нафига оно надо
Для удобной работы с БД.
Что за null-фобия?
Ну первая версия совсем не содержала null. Потом туда прикрутили nullable дженерики. Мне было очень весело когда с одной стороны у меня были int? а с другой int (они не кастяться ни туда ни обратно). Потом стандартные типы постоянно выкидывают всякие эксепшены при попытке работать с null. Например стандартные мапы выкидывали key not found и key is null (или как то так). Т.е. вместо того что б просто вернуть null из мапы если я передал null в качестве ключа, который получил из какого-нить метода, мне приходилось заворачивать всё в if'ы. Сложилось стойкое впечатление что делали так, чтоб NPE никогда не вылетел, в результате наплодили кучу маразма.
Недавно видел код контроллера для javafx, где человек проверяет при нажатии кнопки на нулл сцену, в которой эта кнопка находится. Сразу видно, парни подобное пишут уже на автомате, наученные десятилетиями NullPointerException'а
Теперь можно и нормальные биндинги к Qt написать - очень будет ынтырпрайзно. Вот ты сейчас сидишь ничего не подозреваешь, а кто-то уже стартовал миллионный бизнес.
А я люблю NPE. Это же прекрасно, находить баг. А все эти проверяльщики тупо скрывают свои баги от пользователя. Это как пшикать духами подмышки вместо того, чтобы смыть пот. Лучше наоборот расставить побольше requireNotNull, чтобы NPE вылетел поближе к месту появления неожидаемого null-а.
Не знаю, в джаве дженерики для типизации. Например
class Child{...}
class ChildA extends Child{
...
void methodA(){...};
...
};
class Parent<T extends Child>{
List<T> getChildren{...}
}
class ParentA extends Parent<ChildA>{...}
void doSmth(Parent<ChildA> parent){
for (ChildA ca: parent.getChildren()){ ca.methodA() };
}
Если в жаве добавить
class ChildB extends ChildA{...};
class ParentB extends Parent<ChildB>{...}
То его можно впихнуть в doSmth, а вот в шарпе так не выйдет, потому что List<ChildB> на наследник List<ChildA>. С логической стороны, да, в жаве косяк, за то удобнее.
Судя по всему, и правда не выйдет. Не имею под рукой компилятора, поэтому воспользовался онлайн-сервисом:
class Child {}
class ChildA : Child
{
public void Test()
{
Console.WriteLine(1);
}
}
class Parent<T> where T : Child
{
public List<T> Children;
}
class ChildB : ChildA {}
class ParentA : Parent<ChildA> {}
class ParentB : Parent<ChildB> {}
void DoSmth(Parent<ChildA> parent)
{
foreach (ChildA ch in parent.Children)
ch.Test();
}
public void Main()
{
ParentB p = new ParentB();
p.Children = new List<ChildB>();
DoSmth(p);
}
(33,12): error CS1503: Argument 1: cannot convert from 'ParentB' to 'Parent<ChildA>'
Я запутался :) Можно два идентичных кода, один для Java, другой для C#, чтобы первый компилировался, а второй нет. Я могу представить только случай, когда Java насилуется через не-generic вид, но за такое надо бить по рукам. Когда код на generics компилируется в Java и не компилируется в C#, я представить не могу (хотя допускаю, что такое может быть, вот и хочу увидеть).
А смысл? Конечно, это хорошо, для тех, кто изначально на c# писал, но если человек изначально на джаве писал, то на c# и .net переходить вообще нет смысла.
Я раньше писал на Java, но C# очень уж понравился: 1) IDE не такая тормозная, да и мой код часто работает быстрее, чем на java 2) async, linq, ref, out и другие полезности. В общем, как оказалось, язык достаточно приятный. Я не говорю, что на нём надо писать всё, но чтоб быстро набросать нечто работающее — самое оно.
Минус разве что в том, что нужные библиотеки не всегда можно найти, под Java куда больше всего готового доступно.
Я давно забросил шарп, и проблемы уже толком не помню, но вспомнил примерную логику, которая мне была нужна. Этот пример компилируется на жаве, как его записать для шарпа я не понял.
static abstract class A<T extends B> {
public abstract T method();
}
static class B {}
static class C0 extends B {}
static class C1 extends B {}
static class D0 extends A<C0> {
@Override
public C0 method() {
return new C0();
}
}
static class D1 extends A<C1> {
@Override
public C1 method() {
return new C1();
}
}
A getA(boolean b) {//A<? extends B> getA(boolean b)
if (b) {
return new D0();
} else {
return new D1();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
A a = new Main().getA(true);
a.method();
}
Суть в том, что мне хотелось написать общий обработчик, а потом наклепать его наследников, которые бы хранили несколько параметров.
Ну я и говорю, что ты убираешь generics и пишешь без них, лишая себя каких-либо проверок.
public static void main(String[] args) {
A<? extends B> a = getA(true);
B b = a.method();
}
static A<? extends B> getA(boolean b) {
if (b) {
return new D0();
} else {
return new D1();
}
}
вот такой код нормально скомпилируется где угодно.
linq реально шустрый. Проблемы бывают только в linq2sql который не идеален, но позволяет значительно ускорить разработку. Особенно когда нужно смешивать долбшое количество данных, к примеру несколько тысяч саписей от Сервиса смешав с данными из Базы нужно отдать клиенту. Ручками долго а linq просто идеален для этого.
Да и stored procedures помогут, если DB большая и сложная
Памяти жрёт побольше - это да, но это проблема всех managed языков.
У Java есть проблемы изза которых она жрет память больше чем .Net(не может share libraries) и тормозит на обращении к native libraries(не умеет структуры, указатели, и т.д)
~15 лет назад я именно изза этого и начал изучать C# так как Java просто умирала на задаче. Проект переписали на С++, но прототип на C# вел себя приемлимо.
using System.IO;
using System;
class Program
{
static void Main()
{
A<B> a = getA(true);
B b = a.method();
}
static A<B> getA(bool b) {
if (b) {
return new D0();
} else {
return new D1();
}
}
}
class B {}
class C0 : B {}
class C1 : B {}
interface A<out T> where T: B {
T method();
}
class D0 : A<C0> {
public C0 method() {
return new C0();
}
}
class D1 : A<C1> {
public C1 method() {
return new C1();
}
}
У сишарпа проблемы с обратной совместимостью, так что в энтерпрайз он никогда не попадёт. А вне энтерпрайза джаву и так мало кто использовал.
У Java прoблемы не только
с совместимостью(Oracle до сих пор таскает с собой свой JVM)
c поддержкой(эти козлобараны удалили у меня вочти все версии Java пару дней назад при апгрейде а мне проект в продакшн отправлять)
с безопасностью(Java давно стала основным средством расспространения малвари)
с JVM(особо глупой является type erasure которая порождает проблемы вроде Type casting в C# в котром тупизна решения в JVM приведет к проблемам в рантайме)
с ценой(бесплатная и платная Java)
.Net не идеален, но гораздо ближе к идеалу чем Java
Объективно C# - сборная солянка, но это не означает, что у него от этого есть какие-то неоспоримые практические преимущества.
Объективно код на С# получается короче, нет Diamond problem которую ввели в Java 8, VS лучше Eclipse(особо нравится возможность отмотать дебагер назад), linq, plinq, Async рулят