
Disclamer: Автор не претендует на глубокие познания в Java или C#. Но очень хотелось разобраться в истории происхождения данного мема. Если заметите неточности, то пишите в комментариях, буду рад исправить.
Небольшая историческая справка
1996 год. Джеймс Гослинг со своей командой выпускают язык, над которым усиленно работали последние 5 лет. Этим языком был Java, который стал большим успехом для компании и получил широкое распространение. И в течении четырех лет всё было безмятежно, язык совершенствовался, комьюнити увеличивалось, пр��блемы решались.
Но вот наступает лето 2000 года. Презентация Microsoft. Демонстрируется продукт над которым они работали последние годы. Этим продуктом был .NET Framework, в рамках демонстрации которого показывают C#.
И смотря на его синтаксис у многих возникли невольные ассоциации с Java.
«Вы, ребятки (из Microsoft), все еще не понимаете, это своего рода Java с удаленными надежностью, производительностью и безопасностью»
Джеймс Гослинг - создатель Java
Создатель C# не оставил это без внимания и отметил, что
C# «не является клоном Java» и «гораздо ближе к C++» по своему дизайну
Андрес Хейлсберг - создатель Turbo Pascal, Delphi, C# и TypeScript
Но несмотря на возражения, шлейф клона Java за C# остался до сих пор. Давайте же попробуем понять какие моменты в C# были явно «вдохновлены» Java
C# вдохновляется Java
ООП как основная парадигма. Пожалуй это первое что бросилось всем в глаза. Оба языка имеют C-подобный синтаксис и в первых версиях обязывали создавать программы в рамках классов. Просто сравните два простейших класса и станет понятно, откуда пошли мемы
// Класс на Java class Person { private int age; private String name; public Person(int age, String name) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + "and I`m " + age + "years old."); } }
// Класс на C# using System; class Person { private int age; private string name; public Person(int age, String name) { this.name = name; this.age = age; } public void sayHello() { Console.WriteLine("Hello, my name is " + name + "and I`m " + age + "years old."); } }
Сборщик мусора. На тот момент передовая концепция, которая была скорее в диковинку. Хотя реализация в языках и отличается (Java - алгоритм пометок, C# - алгоритм поколений), не будем отрицать что именно Java значительно популяризировала этот подход


Механизм рефлексии. Рефлексия — это механизм исследования данных о программе во время её выполнения. Этот механизм в присутствовал еще в языках ассемблера, но Java привнесла его в высокоуровневые языки, переработав подход к ним. Что взял на вооружение в том числе и C#
// Рефлексии в Java import java.lang.reflect.Method; public class GetMethodsExample { public static void main(String...args) { Class<GetMethodsExample> c = GetMethodsExample.class; Method[] methods = c.getMethods(); for (Method method : methods) { System.out.println(method); } } public int calcInt(int i) { return 0; } public void doSomething() {} public static void aStaticMethod(String s) {} private void aPrivateMethod() {} }
// Рефлексии в C# using System.Reflection; public class GetMethodsExample { public static void Main() { MethodInfo[] methodInfos = Type.GetType("GetMethodsExample").GetMethods(); foreach(MethodInfo methodInfo in methodInfos) { Console.WriteLine(methodInfo.Name); } } public int calcInt(int i) { return 0; } public void doSomething() {} public static void aStaticMethod(String s) {} private void aPrivateMethod() {} }
Java вдохновляется C#
Но не все так однозначно и впоследствии некоторые решения из C# перетекли в Java.
LINQ. Language Integrated Query — проект Microsoft по добавлению синтаксиса языка запросов, напоминающего SQL, в языки программирования платформы .NET Framework. Впервые LINQ появился в C# в 2007 году и лишь спустя 7 лет подобный функционал появился в Java в виде Streams API
// LINQ class Program { static void Main() { var numbers = new List<int> {1, 2, 3, 4, 5 }; var evenNumbers = numbers.Where(n => n % 2 == 0); var squares = numbers.Select(n => n * n); var sum = numbers.Aggregate((a, b) => a + b); } }
// Streams API import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Stream; public class Example { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); Stream<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0); Stream<Integer> squares = numbers.stream().map(n -> n*n); Optional<Integer> sum = numbers.stream().reduce((a, b) -> a + b); } }
Атрибуты позволяют помечать функции, свойства, классы, методы и т. д. Они появились в C# в 2002 году. В Java такая возможность была названа аннотациями. Несколько встроенных аннотаций появилось в Java в 2004 году, возможность создания собственных аннотаций с различными полями появилась аж в 2013
// Атрибуты в C# class Program { [Obsolete("Method1 is deprecated, please use Method2 instead.")] public void Method() { Console.WriteLine("Устаревший метод"); } public void Method2() { Console.WriteLine("Актуальный метод"); } public static void Main() { new Program().Method(); } }
// Атрибуты в Java public class Program { /** * @deprecated * Method1 is deprecated, please use Method2 instead */ @Deprecated public void Method1() { System.out.println("Устаревший метод"); } public void Method2() { System.out.println("Актуальный метод"); } public static void main(String[] args) { new Program().Method1(); } }
Делегаты. Делегат - класс, который позволяет хранить в себе ссылку на метод с определённой сигнатурой (порядком и типами принимаемых и типом возвращаемого значений) произвольного класса. Они были в C# с момента релиза. В 2014 году в Java были добавлены делегаты в виде функциональных интерфейсов
// Делегаты using System; delegate int Adder(int a, int b); class Program { static void Main(string[] args) { Adder adder = (a, b) => a + b; int result = adder(5, 10); Console.WriteLine(result); } }
// Функциональные интерфейсы @FunctionalInterface interface Adder { int add(int a, int b); } public class Main { public static void main(String[] args) { Adder adder = (a, b) -> a + b; int result = adder.add(5, 10); System.out.println(result); } }
Так каков итог?
Смотря на путь языков Java и C# я прихожу к выводу, что в данный момент мем про копирование C# Java потерял свою актуальность. Конечно подобное можно сказать про многие из программистских мемов, но это уже другая история.
Всем позитива!
