СинтаксисC Sharp синтаксис И двата езика се считат за „curly brace“ (т.е. използват фигурни скоби) програмни езици от фамилията на C и C++. Като цяло синтаксисът им е много сходен, а на ниво „statement“ (твърдения) и „expressions“ (изрази) е почти идентичен, очевидно „вдъхновен“ от традицията на C++. При дефинирането на типове (класове и интерфейси) съществуват някои незначителни различия. В Java имплементирането на интерфейси и разширяването (extend) на класовете се извършва изрично (explicit), докато в C# това се подразбира от типа, наследен от новия клас/интерфейс.

C# поддържа повече функции от Java, което до известна степен е видно и от синтаксиса му, който включва повече ключови думи и повече правила, отколкото Java.

Ключови думи и обратна съвместимост Тъй като езиците еволюират, „дизайнерите“ и на двата езика постоянно се изправят пред ситуации, от които се вижда, че езиците трябва да бъдат разширени с нови ключови думи или синтаксис. Това обаче крие и опасности. Принципно новите ключови думи могат да „счупят“ вече написаният код, т.е. код, написан на по-стара версия на езика, няма да се компилира от компилатора на по-нова версия (няма обратна съвместимост). Дизайнерите на C# и Java, в стремежа си да избегнат такива регресии, подхождат по различен начин при разрешаването на този проблем.

Дизайнерите на Java се опитват да избягват колкото може повече нови ключови думи, предпочитайки да представят нови синтактични конструкции или да преизползват съществуващи ключови думи в нов контекст. По този начин те не застрашават обратната съвместимост. Пример за това е начинът, по който for-цикълът беше разширен, за да може да приема iterable типове. Друг пример е преизползването на ключовите думи „extends“ и „super“ за специфицирането на типовете, когато „generics“ са въведени в Java 1.5.

Дизайнерите на C# са въвели няколо нови ключови думи от представянето на първата версия на езика. Обаче, вместо да се дефинират като глобални, те са въведени като „контекстно-чувствителни“. Това означава, че след въвеждането например на „partial“ и „yield“ като ключови думи в C# 2.0, употребата им като идентификатори все още продължава да бъде валидна, според контекста разбира се. Така настоящият синтаксис на C# е напълно съвместим със сорс кода, написан на предишните версии на езика. Ключова думаПриложениеchecked, uncheckedВ C# блоковете код и изразите, дефинирани като checked, могат run-time да следят за препълване на типовете данни.get, setC# имплементира свойствата (property) на обектите като част от синтаксиса на езика, заедно със средствата за достъп до тях (get, set), като алтернатива на методите за достъп, използвани в Java.gotoC# поддържа ключовата дума goto. Това в някои случаи би било полезно, но използването на този оператор не се препоръчва. В Java goto конструкцията не съществува, но goto е резервирана дума. Все пак Java поддържа конструкциите break и continue, които в определени ситуации могат да се използват по същия начин като gotoswitch(color) { case Color.Blue: Console.WriteLine("Color is blue"); break; case Color.DarkBlue: Console.WriteLine("Color is dark"); goto case Color.Blue; // ... }lockВ C# с lock се осъществява синхронизиран достъп да блокове код през нишки (threads), обвити в try...finally блок.out, refC# поддържа изходящи (out) и референтни (ref) параметри. Това позволява връщането на множество стойности от един метод, или достъпа до стойности по референция.strictfpJava използва strictfp за да гарантира, че резултатите от работата с числа с плаваща запетая ще останат същите за различни платформи.switchcaseВ C# switchcase конструкцията работи също със string и long. Пропадането е позволено за празните case (т.е. без код), а за тези, които съдържат някакъв код, е възможно с „goto case“. Преди Java 7 switchcase конструкцията не е работела с „String“, нито с „long“, но пропадането е позволено за всички case-ове, с изключение на тези, които завършват с break.throwsJava изисква всеки метод да декларира проверените (checked) изключения (exceptions), които може да хвърли.public int readItem() throws java.io.IOException { // ... }usingВ C# използването на using е причина да се изпълни метода Dispose (които е имплементиран чрес интерфейса IDisposable) на декларирания обект след като код-блокът е приключил изпълнението си или е хвърлил изключение (exception).// Create a small file "test.txt", write a string, // ... and close it (even if an exception occurs) using (StreamWriter file = new StreamWriter("test.txt")) { file.Write("test"); }В Java SE 7 е добавена подобна конструкция, наречена try-with-resources :try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); }

Обектно-ориентирано програмиранеОбектно-ориентирано програмиранеComparison of C Sharp and Java Както C#, така и Java са изначално проектирани като обектно–ориентирани езици, със синтаксис, сходен на синтаксиса на C++ (който от своя страна произлиза от C). Не може обаче да се каже, че двата езика са съвкупност от C и C++. Обектно ориентиранеJavaC#КласовеЗадължителниЗадължителниИнтерфейсиДаДаАбстрактни класовеДаДаНива на достъп до член-променливитеДа: public, package, protected, privateДа: public, internal, protected, private, protected internalВмъкнати класове (inner classes)ДаДаАнонимни класовеДаДа (без методи)Частични класовеНеДаСъбития (events)Поддържани от стандартните библиотекиВградени в езикаОвърлоудване на операториНеДаИндексаториНеДаКосвена (implicit) конверсияНеДаИзрична (explicit) конверсияДаДа

Частични класове C# позволява дефиницията на класовете да бъде разделена на няколко части на различни места в сорс кода или в различни изходни файлове посредством съществуването на т. нар. частични класове. В този случай всяка част трябва да бъде обозначена с ключовата дума „partial“. Тези части се събират по време на компилация, което позволява изходния код да е идентичен с този на нечастичните (целите) класове. Различните части имат достъп до елементи от други части на класа. Възможно е една част да дефинира базовия клас, а останалите да имплементират интерфейси.

Основната причина за въвеждането на частични класове е улесняване разработката и имплементирането на генератори на код, например графични/визуални дизайнери. Без частичните класове, генераторите трябва да управляват и вмъкват генерирания от тях код на различни места в оригиналния сорс код. Това поражда редица проблеми както с ефективността на компилатора така и с риск от грешки и повреждане на крайния сорс код. За да се избегне това, генераторите създават своя код в отделни файлове или в грубо дефинирани частични класове и компилаторът минава през фаза на „пред-компилация“ (обединяване на сегментите) преди да продължи с нормалната си работа.

За разлика от механизмите за разширяване на класовете (class extensions) частичният клас позволява „циркулираща“ зависимост между отделните части, тъй като е гарантирано, че те ще бъдат достъпни по време на компилация. Java от своя страна не поддържа тази концепция.

Вмъкнати и локални класове И двата езика позволяват създаването на вмъкнати (вътрешни) класове, като в тези случаи класът е дефиниран лексикално вътре в друг клас. За всеки от езиците обаче тези класове имат различна семантика.

В Java, освен ако вътрешният клас не бъде деклариран като статичен, референцията към него представлява и референция към външния клас. Като резултат кодът във вътрешния клас има достъп както до статичните, така и до нестатичните членове на външния клас. За да бъде създадена инстанция на нестатичен вътрешен клас, тя трябва да бъде именувана като инстанция на обгръщащия го външен клас. Това може да бъде направено посредством въведения с JDK 1.3 оператор „new“: outerClassInstance.new Outer.InnerClass(). Това може да бъде направено във всеки клас, който има референция към инстанция на външния клас.

В C#„Въведение в програмирането със C#“ вмъкнатият клас принципно е почти същият като обикновения клас. В известен смисъл външният клас играе ролята на „namespace“. Следователно кодът във вътрешния клас няма достъп до нестатичните членове на външния клас, освен ако не използва изрична референция към инстанцията на външния клас. Вътрешният клас може да бъде деклариран с ключовата дума „private“, за да се ограничи достъпът до него. Така деклариран, той може да бъде достъпен единствено от външния клас.

Друг тип е локалният (или анонимен) клас, който представлява клас, дефиниран в тялото на метод (функция). И C#, и Java позволяват създаването на такива класове.

В Java„Въведение в програмирането с Java“ тези класове се използват предимно за имплементиране на интерфейси със само един или два метода, които обикновено представляват някакви манипулатори на събития (event handlers), но могат да бъдат използвани също и за пренаписване (override) на т. нар. виртуални методи или суперкласове. Методите в тези локални класове имат достъп до променливите, декларирани като константи (с ключовата дума „final“) във външния метод.

В C# също се поддържат анонимните класове (типове), но с известни разлики от Java. Такъв клас в C# може да бъде инстанциран, само като му се подадат като свойства (properties) множество от имена и съответен израз за инициализирането им. Типовете на тези „properties“ се подразбират от типа на израза, който е подаден.

Овърлоудване на оператори и конверсия Овърлоудването (претоварването) на операторите и дефинираното от потребителя „кастване“ (cast – преобразуване на типа на данните) са отделни функционалности, чиято цел е да се позволи на нови типове данни да бъдат използвани свободно, както всички други типове. Чрез използването им в C# са интегрирани типовете като „complex“ и „decimal“, така че обикновените оператори за събиране, умножение, деление и т.н. да могат свободно да работят с тях. За разлика от C++, в C# претоварването на операторите е ограничено, а за операторите „new“, „()“, „| |“, „&&“, „=“ и за някои вариации на съставните оператори („+=“, „-=“ и т.н.) дори забранено. Важно е обаче да се отбележи, че съставният оператор ще извика поотделно унарните оператори, които може вече да са овърлоуднати (напр. „+=“ извиква „+“ и „=“).

Java не поддържа овърлоудването на операторите, нито „custom“ конверсията, с цел да се предотврати злоупотребата с тази функционалност, както и за да се запази „простотата“ на езика.

Индексатори C# поддържа т.нар. индексатори, които могат да се разглеждат като специфичен случай на овърлоудване на оператори, когато се използват в обектно-ориентираното програмиране (с оператора [ ] се извикват елементите на колекция по индекс, но в случая се използва за индексация на обекти). Индексаторите се имплементират по подобен начин на свойствата (properties).

Индексаторите представляват синтактическо средство, позволяващо създаването на клас, структура или интерфейс, достъп до които може да се осъществява по индекс подобно на масивите (с оператора "[ ]"). За да се дефинира такъв индексатор, се използва ключовата дума „this“.public int this[int index] // Indexer declaration { // get and set accessors }В Java такива индексатори не съществуват. По индекс (с оператора "[ ]") могат да се получат само и единствено елементите на масив.

Полета и инициализация Полета и инициализацияJavaC#ПолетаДаДаКонстантиДаДаСтатични конструкториДаДаДеструктори/финализаториДаДаИнициализация на обектитеОтдолу-нагоре (полета и конструктори)Отгоре-надолу (полета); отдулу-нагоре (конструктори)Обектни инициализаториНеДаИнициализатори на колекцииНе: могат да бъдат симулираниДаИнициализатори на масивиДаДа Както в Java, така и в C# полетата (променливи, които съхраняват данни за обекта) могат да бъдат инициализирани или като променливи, или чрез използването на конструктор. Конструкторите представляват специални подпрограми, които се изпълняват след като обектът бъде създаден.

В C#, когато създадем обект, неговите полета се инициализират в следния ред: Наследени статични полета Наследени инстанции на полета Базови статични полета Базови инстанции на полета