Java и C#. История одного вдохновения

Спиши, но не точь в точь

Спиши, но не точь в точь

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

Алгоритм сборки мусора в Java

Алгоритм сборки мусора в C#

Алгоритм сборки мусора в C#

Механизм рефлексии. Рефлексия — это механизм исследования данных о программе во время её выполнения. Этот механизм в присутствовал еще в языках ассемблера, но Java привнесла его в высокоуровневые языки, переработав подход к ним. Что взял на вооружение в том числе и C#

// Рефлексии в Java

import java.lang.reflect.Method;

public class GetMethodsExample {
    
    public static void main(String...args) {
        Class 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 {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 numbers = Arrays.asList(1, 2, 3, 4, 5);
        Stream evenNumbers = numbers.stream().filter(n -> n % 2 == 0);
        Stream squares = numbers.stream().map(n -> n*n);
        Optional 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 потерял свою актуальность. Конечно подобное можно сказать про многие из программистских мемов, но это уже другая история.

Всем позитива!

© Habrahabr.ru