Xamarin для разработчиков Java

Если вы разработчик Java, вы можете применять свои навыки работы с существующим кодом на платформе Xamarin, получая возможность повторно использовать код C#. Вы заметите, что синтаксис C# очень напоминает синтаксис Java и что оба языка обеспечивают очень схожие функции. Кроме того, вы ознакомитесь с уникальными функциями C#, которые упрощают разработку.

Обзор

Из этой статьи вы узнаете о программировании C# для разработчиков Java, а также ознакомитесь с функциями языка C#, которые используются при разработке приложений Xamarin.Android. Здесь также объясняется, как эти функции отличаются от таких же функций Java. Здесь описываются важные функции C# (применимые к Xamarin.Android), недоступные в Java. В этом руководстве содержатся ссылки на дополнительные справочные материалы, поэтому его можно использовать как стартовую точку для дальнейшего изучения C# и .NET.

Если вы знакомы с Java, понимание синтаксиса C# не вызовет никаких сложностей. Синтаксис C# очень похож на синтаксис Java. C# — это язык фигурной скобки, такой как Java, C и C++. Во многих отношениях синтаксис C# считается расширенным вариантом синтаксиса Java, но с несколькими переименованными и добавленными ключевыми словами.

В C# можно найти многие основные характеристики Java:

  • основанное на классах объектно-ориентированное программирование;

  • строгая типизация;

  • поддержка интерфейсов;

  • Универсальные шаблоны

  • Сбор мусора

  • компиляция среды выполнения.

Java и C# компилируются в промежуточный язык, выполняемый в управляемой среде выполнения. C# и Java являются статически типизированными и распознают строки как неизменяемые типы. Оба языка используют иерархию классов с одним корнем. Подобно Java, C# поддерживает только одно наследование и не позволяет использовать глобальные методы. В этих языках объекты создаются в куче с использованием ключевого слова new и удаляются сборщиком мусора, когда в них больше нет необходимости. Оба языка обеспечивают официальную поддержку обработки исключений с помощью семантики try/catch, а также поддержку синхронизации и управления потоками.

Однако между этими языками есть немало различий. Например:

  • В Java вы можете передавать параметры только по значению, тогда как в C# их можно передавать как по ссылке, так и по значению. (C# предоставляет ключевые слова ref и out для передачи параметров по ссылке. В Java нет эквивалентов.)

  • Java не поддерживает директивы препроцессора, например #define.

  • Java не поддерживает целочисленные типы без знака, а в C# такие типы есть, например ulong, uint, ushort и byte.

  • Java не поддерживает перегрузку операторов. В C# вы можете перегружать операторы и преобразования.

  • В инструкции switch Java код может попасть в следующий раздел switch, но в C# в конце каждого раздела switch должен находиться переключатель (каждый раздел должен закрываться с помощью инструкции break).

  • В Java вы указываете исключения, создаваемые методом с throws ключевое слово, но C# не имеет понятия об проверка исключениях. throws Ключевое слово не поддерживается в C#.

  • C# поддерживает синтаксис LINQ, который позволяет использовать зарезервированные слова from, select и where для написания запросов к коллекциям способом, похожим на запросы к базе данных.

Разумеется, между C# и Java имеется гораздо больше различий, которые никак нельзя рассмотреть в одной статье. Кроме того, Java и C# продолжают развиваться (например, Java 8 — версия, которой еще нет в цепочке инструментов Android, поддерживает лямбда-выражения в стиле C#), поэтому эти различия со временем будут изменяться. Здесь перечислены только самые важные отличия, с которыми в настоящее время сталкиваются разработчики Java, только начинающие изучать расширение Xamarin.Android.

C# предоставляет ряд основных функций Xamarin.Android, которые в настоящее время не доступны для разработчиков Java на Android. С помощью этих функций можно написать качественный код за короткий срок.

  • Свойства — с помощью системы свойств C#можно безопасно и напрямую обращаться к переменным-членам без необходимости записывать методы задания и получения.

  • Лямбда-выражения — в C# можно использовать анонимные методы (также называемые лямбда-выражениями) для выражения функциональных возможностей более кратко и более эффективно. Вы можете избежать сложностей, связанных с необходимостью писать одноразовые объекты, и передать локальное состояние методу без необходимости добавлять параметры.

  • Обработка событий — C# обеспечивает поддержку программирования на уровне языка, где объект может регистрироваться при возникновении интересующего события. Ключевое слово event определяет механизм многоадресного вещания, который класс издателя может использовать для уведомления подписчиков событий.

  • Асинхронное программирование — асинхронное программирование c# (async/await) сохраняет реагирование приложений. Поддержка этой функции на уровне языка упрощает реализацию асинхронного программирования и снижает вероятность ошибок.

И, наконец, Xamarin позволяет использовать имеющиеся ресурсы Java с помощью технологии привязки. Вы можете вызвать имеющийся Java-код, платформы и библиотеки из C# с помощью автоматических генераторов привязки Xamarin. Для этого нужно просто создать статическую библиотеку в Java и предоставить ее C# через привязку.

Примечание.

При программировании в Android используется специальная версия языка Java, которая поддерживает все функции Java 7 и подмножество Java 8.

Некоторые функции, упомянутые на этой странице (например, ключевое слово C# var), доступны в более новых версиях Java (например, var в Java 10), но по-прежнему недоступны разработчикам Android.

Переход от разработки на Java к разработке на C#

В следующих разделах описываются основные базовые различия между C# и Java. В разделе ближе к концу статьи описываются объектно-ориентированные различия между этими языками.

Библиотеки и сборки

Java обычно упаковывает связанные классы в JAR-файлы. Однако в C# и .NET предварительно скомпилированный код, который можно многократно использовать, упаковывается в сборки, которые обычно объединяются в пакет как DLL-файлы. Сборка — это единица развертывания кода C# или .NET. Каждая сборка обычно связана с проектом C#. Сборки содержат промежуточный код, который компилируется в среде выполнения по методу JIT.

Дополнительные сведения о сборках см. в разделе Сборки и глобальный кэш сборок.

Пакеты и пространства имен

C# использует ключевое слово namespace, чтобы сгруппировать связанные типы. В Java эквивалентом является ключевое слово package. Обычно приложение Xamarin.Android размещается в пространстве имен, созданном для него. Например, следующий код C# объявляет программу-оболочку пространства имен WeatherApp для приложения отправки отчетов о погоде:

namespace WeatherApp
{
    ...

Импорт типов

Когда вы используете типы, определенные во внешних пространствах имен, вы импортируете их с помощью инструкции using (которая очень похожа на инструкцию import Java). В Java вы можете импортировать один тип с инструкцией, подобной следующей:

import javax.swing.JButton

Вы можете импортировать весь пакет Java с помощью инструкции, подобной ниже:

import javax.swing.*

Инструкция using C# работает очень схожим образом, но она позволяет вам импортировать весь пакет без указания подстановочного знака. Например, вы будете часто встречать серию инструкций using в начале исходных файлов Xamarin.Android, как показано в этом примере:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Net;
using System.IO;
using System.Json;
using System.Threading.Tasks;

С помощью этих инструкций импортируются функции из System, Android.App, Android.Content и других пространств имен.

Универсальные шаблоны

Java и C# поддерживают универсальные шаблоны, которые являются заполнителями, позволяющими подключаться к различным типам во время компиляции. Однако в C# универсальные шаблоны работают несколько иначе. В Java при использовании стирания типа сведения становятся доступными только во время компиляции, а не выполнения. И напротив, среда выполнения CLR .NET обеспечивает явную поддержку универсальных типов. Это означает, что в этой среде у C# есть доступ к сведениям о типах. В повседневной разработке Xamarin.Android важность этого различия не всегда очевидна, но если вы используете отражение, именно эта функция будет определять доступ к сведениям о типах во время выполнения.

В Xamarin.Android вы будете часто видеть универсальный метод FindViewById, используемый для получения ссылки на элемент управления макета. Этот метод принимает параметр универсального типа, который определяет тип элемента управления для поиска. Например:

TextView label = FindViewById<TextView> (Resource.Id.Label);

В этом примере кода метод FindViewById получает ссылку на элемент управления TextView, который определен в макете как метка, а затем возвращает его как тип TextView.

Дополнительные сведения об универсальных шаблонах см. в статье Универсальные шаблоны. Обратите внимание, что в поддержке Xamarin.Android есть некоторые ограничения для универсальных классов C#. Дополнительные сведения см. в этом разделе.

Функции объектно-ориентированного программирования

Java и C# используют очень похожие способы объектно-ориентированного программирования.

  • Все классы в конечном счете являются производными от одного корневого объекта — все объекты Java являются производными от java.lang.Objectвсех объектов System.ObjectC#.

  • Экземпляры классов являются ссылочными типами.

  • Когда вы обращаетесь к свойствам и методам экземпляра, вы используете оператор ..

  • Все экземпляры классов создаются в куче через оператор new.

  • Так как оба языка используют сборку мусора, явно освободить неиспользуемые объекты невозможно (т. е. в этих языках нет ключевого слова delete, как в C++).

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

  • Вы можете определить интерфейсы, а класс может наследовать (например, реализовывать) функции из нескольких определений интерфейсов.

Однако есть и некоторые важные отличия.

  • Java поддерживает две эффективные функции, которые не поддерживаются в C#: анонимные классы и внутренние. (Однако C# разрешает вложение определений классов— вложенные классы C#похожи на статические вложенные классы Java.)

  • C# в отличие от Java поддерживает типы структуры стиля C (struct).

  • В C# вы можете реализовать определение класса в отдельных исходных файлах с использованием ключевого слова partial.

  • Интерфейсы C# не могут объявлять поля.

  • C# использует синтаксис деструктора стиля C++ для выражения методов завершения. Синтаксис отличается от метода finalize Java, но семантика почти одинакова. (Обратите внимание, что в C#деструкторы автоматически вызывают деструктор базового класса, в отличие от Java, где используется явный вызов super.finalize .)

Наследование классов

Чтобы расширить класс в Java, нужно использовать ключевое слово extends. Чтобы расширить класс в C#, нужно использовать двоеточие (:) для указания наследования. Например, в приложениях Xamarin.Android вы будете часто встречать наследования классов, которые напоминают фрагмент кода ниже:

public class MainActivity : Activity
{
    ...

В этом примере MainActivity наследуется от класса Activity.

Чтобы объявить поддержку интерфейса в Java, нужно использовать ключевое слово implements. Однако в C# нужно просто добавить имена интерфейсов в список классов, которые будут использоваться для наследования, как показано в этом фрагменте кода:

public class SensorsActivity : Activity, ISensorEventListener
{
    ...

В этом примере SensorsActivity наследуется от Activity и реализует функцию, объявленную в интерфейсе ISensorEventListener. Обратите внимание, что список интерфейсов должен следовать за базовым классом (в противном случае вы получите ошибку времени компиляции). По соглашению к именам интерфейсов C# добавляется "I" в верхнем регистре, что позволяет определить без ключевого слова implements, какие классы являются интерфейсами.

Если вы хотите предотвратить дальнейшее подклассы класса в C#, перед именем класса перед именем класса в Java предшествует имя sealed класса.final

Дополнительные сведения об определениях классов C# см. в разделах Классы и Наследование.

Свойства

В Java методы-мутаторы (методы задания) и методы-инспекторы (методы получения) часто используются для управления способами применения изменений к элементам класса со скрытием и защитой этих элементов от внешнего кода. Например, класс TextView Android предоставляет методы getText и setText. C# обеспечивает аналогичный, но более прямой механизм, известный как свойства. Пользователи класса C# могут получить доступ к свойству так же, как они получают доступ к полю, но каждый доступ фактически приводит к вызову метода, который является прозрачным для вызывающего. Этот "неявный" метод может включать побочные эффекты, например установку других значений, выполнение преобразований или изменение состояния объекта.

Свойства часто используются для доступа к элементам объектов пользовательского интерфейса и их изменения. Например:

int width = rulerView.MeasuredWidth;
int height = rulerView.MeasuredHeight;
...
rulerView.DrawingCacheEnabled = true;

В этом примере значения ширины и высоты считываются из объекта rulerView путем доступа к его свойствам MeasuredWidth и MeasuredHeight. Когда эти свойства считываются, значения из их связанных (но скрытых) значений полей извлекаются в фоновом режиме и возвращаются вызывающему. В объекте rulerView значения ширины и высоты могут храниться в одной единице измерения (например, пикселях) и мгновенно преобразовываться в другие единицы измерения (например, миллиметры) при получении доступа к свойствам MeasuredWidth и MeasuredHeight.

Объект rulerView также имеет свойство, называемое DrawingCacheEnabled — пример кода задает это свойство для true включения кэша рисования в rulerView. В фоновом режиме связанное скрытое поле обновляется новым значением, и, возможно, изменяются другие аспекты состояния rulerView. Например, если свойству DrawingCacheEnabled задано значение false, представление rulerView может также удалить все сведения о кэше документа, накопленные в объекте.

Доступ к свойствам может предоставляться для чтения или записи, только для чтения или только для записи. Кроме того, вы можете использовать разные модификаторы доступа для чтения и записи. Например, вы можете определить свойство с открытым доступом на чтение, но частным доступом на запись.

Дополнительные сведения о свойствах C# см. в разделе Свойства.

Вызов методов базового класса

Чтобы вызвать конструктор базового класса в C#, нужно ввести двоеточие (:), затем добавить ключевое слово base и список инициализаторов. Этот вызов конструктора base будет следовать сразу после выходного списка его параметров. Конструктор базового класса вызывается в записи в производный конструктор. Компилятор вставляет вызов в базовый конструктор в начале текста метода. В следующем фрагменте кода показан базовый конструктор, вызванный из производного конструктора в приложении Xamarin.Android:

public class PictureLayout : ViewGroup
{
    ...
    public PictureLayout (Context context)
           : base (context)
    {
        ...
    }
    ...
}

В этом примере класс PictureLayout является производным от класса ViewGroup. Конструктор PictureLayout, показанный в этом примере, принимает аргумент context и передает его в конструктор ViewGroup через вызов base(context).

Чтобы вызвать метод базового класса в C#, используйте ключевое слово base. Например, приложения Xamarin.Android часто вызывают базовые методы, как показано ниже:

public class MainActivity : Activity
{
    ...
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

В этом случае метод OnCreate, определенный производным классом (MainActivity), вызывает метод OnCreate базового класса (Activity).

Модификаторы доступа

Java и C# поддерживают модификаторы доступа public, private и protected. Однако C# поддерживает два дополнительных модификатора доступа:

  • internal — член класса доступен только в текущей сборке.

  • protected internal — Член класса доступен в определяющей сборке, определяемом классе и производных классах (производные классы как внутри, так и вне сборки имеют доступ).

Дополнительные сведения о модификаторах доступа в C# см. в статье Модификаторы доступа.

Виртуальные методы и методы переопределения

Java и C# поддерживают полиморфизм — способность обрабатывать связанные объекты одинаковым образом. Для двух языков вы можете использовать ссылку базового класса для ссылки на объект производного класса, а методы производного класса могут переопределять методы базовых классов этого производного класса. Оба языка включают понятие виртуального метода — метода базового класса, который заменяется методом производного класса. Как и Java, C# поддерживает классы и методы abstract.

Однако есть некоторые различия между Java и C#, а именно в объявлении виртуальных методов и их переопределении.

  • В C# методы по умолчанию не виртуальные. Родительские классы должны явно указывать, какие методы нужно переопределить с помощью ключевого слова virtual. И напротив, все методы в Java являются виртуальными методами по умолчанию.

  • В C#, чтобы предотвратить переопределение метода, вы просто не указываете ключевое слово virtual. В Java же для этого, напротив, нужно указать ключевое слово final.

  • В производных классах C# должно использоваться ключевое слово override, чтобы явно указать, что виртуальный метод базового класса переопределяется.

Дополнительные сведения о поддержке полиморфизма в C# см. в статье Полиморфизм.

Лямбда-выражения

C# позволяет создавать замыкания: встроенные анонимные методы, с помощью которых можно получить доступ к состоянию метода, в который они вложены. Используя лямбда-выражения, вы можете написать меньше строк кода для реализации функций, которые в Java требуют большого количества строк кода.

Лямбда-выражения позволяют пропустить дополнительную церемонию, связанную с созданием одноразового или анонимного класса, так как в Java можно просто написать бизнес-логику встроенного кода метода. Кроме того, так как у лямбда-выражений есть доступ к переменным в окружающем методе, вам не нужно создавать длинный список параметров для передачи состояния в свой код метода.

В C# лямбда-выражения создаются с помощью оператора =>, как показано ниже:

(arg1, arg2, ...) => {
    // implementation code
};

В Xamarin.Android лямбда-выражения часто используются для определения обработчиков событий. Например:

button.Click += (sender, args) => {
    clickCount += 1;    // access variable in surrounding code
    button.Text = string.Format ("Clicked {0} times.", clickCount);
};

В этом примере код лямбда-выражения (код в фигурных скобках) увеличивает количество щелчков и обновляет текст button для указания этого числа. Это лямбда-выражение регистрируется с помощью объекта button как обработчик событий щелчка, который будет вызываться каждый раз при нажатии кнопки. (Обработчики событий подробно описаны ниже.) В этом простом примере senderargs и параметры не используются лямбда-кодом выражения, но они необходимы в лямбда-выражении для удовлетворения требований сигнатуры метода для регистрации событий. В сущности, компилятор C# преобразует лямбда-выражение в анонимный метод, который вызывается всякий раз при нажатии кнопки.

Дополнительные сведения о лямбда-выражениях C# см. в статье Лямбда-выражения.

Обработка событий

Событие — это способ объекта уведомлять зарегистрированных подписчиков об интересных событиях, связанных с этим объектом. В отличие от Java, где подписчик обычно реализует интерфейс Listener, содержащий метод обратного вызова, C# обеспечивает поддержку на уровне языка для обработки событий через делегаты. Делегат похож на указатель на объектно-безопасный тип функции. Он инкапсулирует ссылку на объект и маркер метода. Если клиентский объект хочет подписаться на событие, он создает делегат и передает его уведомляющему объекту. Когда происходит событие, уведомляющий объект вызывает метод, представленный объектом делегата, уведомляя подписавшийся клиентский объект о событии. В C# обработчики событий — это по сути методы, вызываемые через делегаты.

Дополнительные сведения о делегатах см. в статье Делегаты.

В C# события являются многоадресными. Это означает, что о возникновении события могут быть уведомлены несколько прослушивателей. Это различие наблюдается при рассмотрении синтаксических отличий между регистрацией событий в Java и C#. В Java вы вызываете SetXXXListener для регистрации уведомлений о событиях. В C# вы используете оператор += для регистрации уведомлений о событиях путем "добавления" своего делегата в список прослушивателей событий. В Java для отмены регистрации вы вызываете SetXXXListener, а в C# вы используете оператор -=, чтобы вычесть делегат из списка прослушивателей.

В Xamarin.Android события часто используются для уведомления объектов, если пользователь применяет какие-либо действия к элементу управления пользовательского интерфейса. Обычно такой элемент управления содержит элементы, определенные с помощью ключевого слова event. Чтобы подписаться на события из этого элемента управления пользовательского интерфейса, нужно вложить свои делегаты в эти элементы.

Чтобы подписаться на событие, сделайте следующее:

  1. Создайте объект-делегат, который ссылается на метод, который должен вызываться при возникновении события.

  2. Используйте оператор +=, чтобы вложить делегат в событие, на которое вы подписываетесь.

В следующем примере определяется делегат (с явным использованием ключевого слова delegate) для подписки на событие нажатий кнопки. Этот обработчик нажатия кнопки запускает новое действие:

startActivityButton.Click += delegate {
    Intent intent = new Intent (this, typeof (MyActivity));
    StartActivity (intent);
};

Однако вы также можете использовать лямбда-выражение для регистрации событий, пропуская ключевое слово delegate. Например:

startActivityButton.Click += (sender, e) => {
    Intent intent = new Intent (this, typeof (MyActivity));
    StartActivity (intent);
};

В этом примере объект startActivityButton содержит событие, ожидающее делегат с определенной сигнатурой метода: делегат, который принимает аргументы отправителя и события и возвращает пустое значение. Однако, чтобы избежать явного определения такого делегата или его метода, мы объявляем сигнатуру метода с помощью (sender, e) и используем лямбда-выражение для реализации тела обработчика события. Обратите внимание, что нам нужно объявить этот список параметров, даже если параметры sender и e не используются.

Важно помнить, что вы можете отменить подписку делегата (через -= оператор), но вы не можете отменить подписку лямбда-выражения, пытаясь сделать это, может привести к утечке памяти. Используйте лямбда-форму регистрации событий, только если обработчик не отменит подписку на событие.

Как правило, лямбда-выражения используются для объявления обработчиков событий в коде Xamarin.Android. Этот простой способ объявления обработчиков событий может показаться сначала непонятным, но он сокращает время написания и чтения кода. С постоянной практикой вы привыкнете распознавать этот шаблон (который часто встречается в коде Xamarin.Android), сможете уделить больше времени бизнес-логике своего приложения и сократить время изучения синтаксических операций.

Асинхронное программирование

Асинхронное программирование дает возможность повысить общую скорость реагирования приложения. Функции асинхронного программирования позволяют продолжить выполнение оставшихся разделов кода приложения, в то время как часть приложения блокируется длительной операцией. Доступ к Интернету, обработка изображений и чтение или запись файлов — примеры операций, которые могут привести к остановке приложения, если оно не написано с использованием асинхронного программирования.

C# обеспечивает поддержку (на уровне языка) асинхронного программирования с помощью ключевых слов async и await. Эти языковые функции позволяют легко писать код, который выполняет длительные задачи без блокирования основного потока приложения. Коротко говоря, вы используете в методе ключевое слово async, чтобы указать, что код в этом методе должен выполняться асинхронно, а не блокировать поток вызывающего. При вызове методов, помеченных async, будет использоваться ключевое слово await. Компилятор интерпретирует await как точку, в которой выполнение метода должно переместиться в фоновый поток (задача возвращается вызывающему). Когда эта задача завершается, выполнение кода возобновляется в потоке вызывающего в точке await кода, возвращая результаты вызова async. По правилам к именам методов, которые выполняются асинхронно, добавляется суффикс Async.

В приложениях Xamarin.Android async и await обычно используются, чтобы освободить поток пользовательского интерфейса для его реагирования на ввод данных пользователем (например, нажатие кнопки Отмена), в то время как длительная операция выполняется в фоновом задании.

В следующем примере обработчик события нажатия кнопки вызывает асинхронную операцию для загрузки изображения из Интернета:

downloadButton.Click += downloadAsync;
...
async void downloadAsync(object sender, System.EventArgs e)
{
    webClient = new WebClient ();
    var url = new Uri ("http://photojournal.jpl.nasa.gov/jpeg/PIA15416.jpg");
    byte[] bytes = null;

    bytes = await webClient.DownloadDataTaskAsync(url);

    // display the downloaded image ...

В этом примере, когда пользователь щелкает элемент управления downloadButton, обработчик событий downloadAsync создает объекты WebClient и Uri для получения изображения из указанного URL-адреса. Затем с помощью этого URL-адреса он вызывает метод DownloadDataTaskAsync объекта WebClient для извлечения изображения.

Обратите внимание, что перед объявлением метода downloadAsync указывается ключевое слово async для обозначения асинхронного выполнения метода и возвращения задачи. Также обратите внимание, что вызову метода DownloadDataTaskAsync предшествует ключевое слово await. Приложение перемещает выполнение обработчика событий (начиная с точки, где появляется await) в фоновый поток до завершения и возвращения метода DownloadDataTaskAsync. Между тем, поток пользовательского интерфейса приложения все еще может реагировать на ввод данных пользователем и запускать обработчики событий для других элементов управления. После завершения метода DownloadDataTaskAsync (что может занять несколько секунд) выполнение возобновляется, где переменной bytes задается результат вызова метода DownloadDataTaskAsync, а оставшаяся часть кода обработчика событий отображает загруженное изображение в потоке пользовательского интерфейса вызывающего.

Обзор async/await в C# см. в статье Асинхронное программирование с использованием ключевых слов async и await. Дополнительные сведения о поддержке в Xamarin функций асинхронного программирования см. в этой статье.

Различия в ключевых словах

Многие ключевые слова, используемые в Java, также используются в C#. Имеется также ряд ключевых слов Java, которые имеют аналоги в C#, но с другими именами:

Java C# Description
boolean bool Используется для объявления логических значений true и false.
extends : Предшествует классу и интерфейсам наследования.
implements : Предшествует классу и интерфейсам наследования.
import using Импортирует типы из пространства имен, также используется для создания псевдонима пространства имен.
final sealed Предотвращает наследование классов. Предотвращает переопределение методов и свойств в производных классах.
instanceof is Определяет, совместим ли объект с указанным типом.
native extern Объявляет метод, который реализуется извне.
package namespace Объявляет область для связанного набора объектов.
T... params T Задает параметр метода, который принимает переменное количество аргументов.
super base Используется для доступа к элементам родительского класса из производного класса.
synchronized lock Заключает в оболочку критический раздел кода с применением и снятием блокировки.

Кроме того, есть много ключевых слов, уникальных для C# и не имеющих аналогов в Java, используемом на Android. В коде Xamarin.Android часто используются следующие ключевые слова C# (эту таблицу можно использовать при чтении примера кода Xamarin.Android):

C# Description
as Выполняет преобразования между совместимыми ссылочными типами или типами, допускающими значение null.
async Указывает, что метод или лямбда-выражение являются асинхронными.
await Приостанавливает выполнение метода до завершения задачи.
byte Тип 8-разрядного целого числа без знака.
delegate Используется для инкапсуляции метода или анонимного метода.
enum Объявляет перечисление, набор именованных констант.
event Объявляет событие в классе издателя.
fixed Предотвращает перемещение переменной.
get Определяет метод доступа, который извлекает значение свойства.
в папке Позволяет параметру принимать в универсальном интерфейсе тип с меньшей глубиной наследования.
object Псевдоним для типа Object в .NET Framework.
out Модификатор параметра или объявление параметра универсального типа.
override Расширяет или изменяет реализацию наследованного элемента.
partial Объявляет определение, которое нужно разбить на несколько файлов, или отделяет определение метода от его реализации.
readonly Объявляет, что элемент класса можно назначить только во время объявления или с помощью конструктора класса.
ref; Используется для передачи аргумента по ссылке, а не по значению.
set Определяет метод доступа, который устанавливает значение свойства.
string Псевдоним для типа String в .NET Framework.
struct Тип значения, который инкапсулирует группу связанных переменных.
typeof Получает тип объекта.
var Объявляет неявно типизированную локальную переменную.
значение Ссылается на значение, которое код клиента должен присвоить свойству.
virtual Позволяет переопределить метод в производном классе.

Взаимодействие с имеющимся кодом Java

При наличии функций Java, которые вы не хотите преобразовывать в C#, вы можете повторно использовать имеющиеся библиотеки Java в приложениях Xamarin.Android с помощью двух методов.

  • Создайте библиотеку привязок Java. С помощью этого подхода вы используете средства Xamarin для создания оболочки C# для типов Java. Эти программы-оболочки называются привязками. В результате с помощью вызова этих программ приложение Xamarin.Android может использовать JAR-файл.

  • Собственный интерфейс Java. Собственный интерфейс Java (JNI) — это платформа, которая позволяет приложениям C# вызывать или вызывать код Java.

Дополнительные сведения об этих методах см. в статье обзора интеграции Java.

Дополнительные материалы

Руководство по программированию C# MSDN содержит основные сведения о языке программирования C#, а в справочнике по C# вы сможете найти определенные функции.

В то время, как для изучения языка Java необходимо как минимум ознакомиться с библиотеками класса этого языка, практическая работа с C# требует предварительного знакомства с .NET Framework. Обучающий пакет Майкрософт, содержащий ресурсы о переходе на C# и .NET Framework для Java-разработчиков, — оптимальный способ узнать больше о .NET Framework с точки зрения Java (при подробном изучении C#).

Когда вы будете готовы заняться своим первым проектом Xamarin.Android в C#, с помощью серии Hello, Android вы сможете создать свое первое приложение Xamarin.Android и расширить знания основ разработки приложений Android с Xamarin.

Итоги

В этой статье содержатся общие сведения о среде программирования C# для Xamarin.Android с точки зрения разработчика Java, а также рассматриваются сходства и различия между C# и Java. В этой статье мы рассмотрели сборки и пространства имен, импорт внешних типов, а также ознакомились с обзором различий в модификаторах доступа, универсальными шаблонами, наследованием классов, вызовом методов базового класса, переопределением методов и обработкой событий. Из этого руководства мы узнали о таких функциях C#, недоступных в Java, как свойства, асинхронное программирование с ключевыми словами async/await, лямбда-выражения, делегаты C# и система обработки событий C#. Здесь также содержатся таблицы важных ключевых слов C#, приведены сведения о взаимодействии с имеющимися библиотеками Java и включены ссылки на связанную документацию для дальнейшего изучения.