Objective-C 開発者向けの C# 入門書C# Primer for Objective-C Developers

Xamarin.iOS では、C# で記述されたプラットフォームに依存しないコードをプラットフォーム間で共有できます。ただし、既存の iOS アプリケーションは既に作成されている Objective-C コードを活用できます。この記事は、Xamarin と C# 言語への移行を検討している Objective-C 開発者向けの簡単な入門となります。Xamarin.iOS allows platform-agnostic code written in C# to be shared across platforms. However, existing iOS applications may want to leverage Objective-C code that has already been created. This article serves as a short primer for Objective-C developers looking to move to Xamarin and the C# language.

Objective-C で開発された iOS および macOS アプリケーションでは、プラットフォーム固有のコードが必要ない場所で C# を利用することにより、Xamarin のメリットを得られます。そのようなコードは、Apple 以外のデバイスで使用できます。iOS and macOS applications developed in Objective-C can benefit from Xamarin by leveraging C# in places where platform-specific code is not required, allowing such code to be used on non-Apple devices. Web サービス、JSON と XML の解析、カスタム アルゴリズムなどをクロスプラットフォーム方式で使用できます。Things such as web services, JSON and XML parsing, and custom algorithms can then be used in a cross-platform manner.

Objective-C の既存の資産を維持しながら Xamarin を利用するには、バインディングと呼ばれる Xamarin のテクノロジでこれを C# に公開できます。バインディングは、Objective-C コードをマネージドな C# の世界に公開します。To take advantage of Xamarin while maintaining existing Objective-C assets, the former can be exposed to C# in a technology from Xamarin known as bindings, which surface Objective-C code to the managed, C# world. また、必要な場合はコードを行ごとに C# に移植することもできます。Also, if desired, code can be ported line-by-line to C# as well. ただし、バインディングと移植のどちらのアプローチであっても、既存の Objective-C コードを Xamarin.iOS で効果的に活用するには Objective-C と C# の知識がある程度必要です。Regardless of the approach however, whether it be binding or porting, some knowledge of both Objective-C and C# is necessary to effectively leverage existing Objective-C code with Xamarin.iOS.

Objective-C との相互運用Objective-C Interop

現在、Xamarin.iOS を使用して Objective-C から呼び出すことができる C# のライブラリを作成するメカニズムはサポートされていません。There is currently no supported mechanism to create a library in C# using Xamarin.iOS that can be called from Objective-C. その主な理由は、バインディングに加えて Mono ランタイムも必要であるためです。The main reason for this is the Mono runtime is also required in addition to the binding. ただし、ユーザー インターフェイスを含め、Objective-C のロジックの大部分を作成できます。However, you can still create the majority of your logic in Objective-C, including user interfaces. これを行うには、ライブラリに Objective-C コードをラップし、それに対するバインディングを作成します。To do this, wrap the Objective-C code in a library and create a binding to it. Xamarin.iOS はアプリケーションのブートストラップに必要です (つまり、Main エントリ ポイントを作成する必要があります)。Xamarin.iOS is needed to bootstrap the application (meaning it must create the Main entry point). その後、他のロジックを Objective-C に作成して、バインディングによって (または P/Invoke を使用して) C# に公開されます。After that, any other logic can be in Objective-C, exposed to C# through the binding (or via P/Invoke). これにより、Objective-C にプラットフォーム固有のロジックを保持し、C# でプラットフォームに依存しない部分を開発できます。This way, you can keep the platform specific logic in Objective-C and develop the platform agnostic parts in C#.

この記事は、両方の言語の主要な類似点の一部に注目すると共に、いくつかの違いを比較しており、既存の Objective-C コードへのバインディングか C# への移植かにかかわらず、Xamarin.iOS を使用する C# に移行する際の入門として利用できます。This article highlights some key similarities, as well as contrasts several differences in both languages to serve as a primer when moving to C# with Xamarin.iOS, whether binding to existing Objective-C code, or porting it to C#.

バインディングの作成について詳しくは、Objective-C のバインディングに関する記事に記載されている他のドキュメントをご覧ください。For details on creating bindings see the other documents in Binding Objective-C.

言語の比較Language Comparison

Objective-C と C# は、構文とランタイムの観点からはまったく異なる言語です。Objective-C and C# are very different languages both syntactically and from a runtime standpoint. Objective-C は動的言語であり、メッセージ パッシング スキームを使用します。一方、C# は静的に型指定されます。Objective-C is a dynamic language and uses a message passing scheme, whereas C# is statically typed. 構文の観点では、Objective-C は Smalltalk に似ており、C# はその基本的な構文の多くが Java から派生していますが、ここ数年で成熟し、Java を超える多くの機能が含まれています。Syntax-wise, Objective-C is like Smalltalk, whereas C# derives much of its fundamental syntax from Java, although it has matured to include many capabilities beyond Java in recent years.

とは言うものの、Objective-C と C# のいくつかの言語機能は機能的に似ています。That said there are several language features of both Objective-C and C# that are similar in function. C# から Objective-C コードへのバインディングを作成する場合、または Objective-C を C# に移植する場合は、こうした類似性を理解することが役立ちます。When creating a binding to Objective-C code from C# or when porting Objective-C to C#, understanding these similarities is useful.

プロトコルとインターフェイスProtocols vs. Interfaces

Objective-C と C# はどちらも単一継承言語です。Both Objective-C and C# are single inheritance languages. ただし、どちらの言語も、特定のクラスでの複数のインターフェイスの実装をサポートしています。However, both languages have support for implementing multiple interfaces in a given class. Objective-C では、これらの論理インターフェイスは "プロトコル" と呼ばれ、C# では "インターフェイス" と呼ばれます。In Objective-C these logical interfaces are called protocols whereas in C# they are called interfaces. 実装の観点からは、C# インターフェイスと Objective-C プロトコルの主な違いは、Objective-C ではオプションのメソッドを使用できることです。Implementation-wise, the main difference between a C# interface and an Objective-C protocol is the latter can have optional methods. 詳しくは、「Events, Delegates and Protocols」(イベント、デリゲート、プロトコル) の記事をご覧ください。For more information see the Events, Delegates and Protocols article.

カテゴリと拡張メソッドCategories vs. Extension methods

Objective-C では、"カテゴリ" を使用して、実装コードがないクラスにメソッドを追加できます。Objective-C allows methods to be added to a class for which you may not have the implementation code using Categories. C# では、"拡張メソッド" と呼ばれるものを通じて同様の概念を利用できます。In C# a similar concept is available through what’s known as extension methods.

拡張メソッドでは、クラスに静的メソッドを追加できます。C# の静的メソッドは Objective-C のクラス メソッドに似ています。Extension methods let you add static methods to a class, where static methods in C# are analogous to class methods in Objective-C. たとえば、次のコードは ScrollToBottom という名前のメソッドを UITextView クラスに追加します。このクラスは UIKit から Objective-C の UITextView クラスにバインドされているマネージド クラスです。For example, the following code adds a method named ScrollToBottom to the UITextView class, which in turn is a managed class that is bound to the Objective-C UITextView class from UIKit:

public static class UITextViewExtensions
{
    public static void ScrollToBottom (this UITextView textView)
    {
        // code to scroll textView
    }
}

その後、UITextView のインスタンスがコードに作成されると、メソッドは次に示すようにオートコンプリートの一覧で使用可能になります。Then, when an instance of a UITextView is created in code, the method will be available in the autocomplete list as shown below:

オートコンプリートで使用できるメソッド

拡張メソッドが呼び出されるときに、インスタンスはこの例の textView のような引数に渡されます。When the extension method is called the instance is passed to the argument, such as the textView in this example.

フレームワークとアセンブリFrameworks vs. Assemblies

Objective-C は、関連するクラスをフレームワークと呼ばれる特殊なディレクトリにパッケージ化します。Objective-C packages related classes in special directories known as frameworks. 一方、C# と .NET では、アセンブリはプリコンパイルされたコードの再利用可能な部分を提供するために使用されます。In C# and .NET however, assemblies are used to provide reusable bits of precompiled code. iOS の外部での環境では、アセンブリには、実行時に Just-In-Time (JIT) でコンパイルされる中間言語コード (IL) が含まれています。In environments outside of iOS, assemblies contain intermediate language code (IL) that is just in time (JIT) compiled at runtime. ただし、App Store でリリースされた iOS アプリケーションで、JIT コンパイルのコードを実行することはできません。However, Apple does not allow execution of JIT compiled code in iOS applications released on the App Store. そのため、Xamarin を使用する iOS をターゲットとする C# コードは Ahead Of Time (AOT) でコンパイルされ、アプリケーション バンドルに含まれるメタデータ ファイルと共に単一の UNIX 実行可能ファイルを生成します。Therefore C# code targeting iOS with Xamarin is ahead of time compiled (AOT), producing a single Unix executable along with metadata files that are included in the application bundle.

セレクターと名前付きパラメーターSelectors vs. Named Parameters

Objective-C メソッドでは、その性質上、セレクターにパラメーターが含まれます。Objective-C methods inherently include parameter names in selectors by their very nature. たとえば、AddCrayon:WithColor: などのセレクターは、各パラメーターがコードで使用される場合に何を意味するかを明確にします。For example a selector such as AddCrayon:WithColor: makes it clear what each parameter means when used in code. C# はオプションで名前付き引数もサポートします。C# optionally supports named arguments as well.

たとえば、名前付き引数を使用した C# の同様のコードは次のようになります。For example, similar code in C# using named arguments would be:

AddCrayon (crayon: myCrayon, color: UIColor.Blue);

C# 言語ではこのサポートがバージョン 4.0 で追加されましたが、実際にはめったに使用されません。Although C# added this support in version 4.0 of the language, in practice it isn’t used very often. ただし、コードで明示する必要がある場合は、これでサポートされます。However, if you want to be explicit in your code, the support for it is there.

ヘッダーと名前空間Headers and Namespaces

C のスーパー セットである Objective-C は、実装ファイルから独立したパブリック宣言用のヘッダーを使用します。Being a superset of C, Objective-C uses headers for public declarations that are separate from the implementation file. C# では、ヘッダー ファイルは使用されません。C# does not use header files. Objective-C とは異なり、C# コードは名前空間に含まれます。Unlike Objective-C, C# code is contained in namespaces. 一部の名前空間で使用可能なコードを含める場合は、実装ファイルの先頭にディレクティブを使用して追加するか、完全な名前空間で型を修飾します。If you want to include code available in some namespace, you add either a using directive to the top of the implementation file, or you qualify the type with the full namespace.

たとえば、次のコードには UIKit 名前空間が含まれているため、その名前空間内のすべてのクラスを実装に使用できます。For example, the following code includes the UIKit namespace, making every class in that namespace available to the implementation:

using UIKit;
namespace MyAppNamespace
{
    // implementation of classes
}

また、上記のコードの namespace キーワードは、実装ファイル自体に対して使用する名前空間を設定します。Also, the namespace keyword in the above code sets the namespace used for the implementation file itself. 複数の実装ファイルが同じ名前空間を共有する場合、ディレクティブの使用に名前空間を含める必要はありません。暗黙的に指定されます。If multiple implementation files share the same namespace, there’s no need to include the namespace in a using directive as well, as it is implied.

プロパティProperties

Objective-C と C# の両方に、アクセサー メソッドに関連する高度な抽象化を提供するプロパティの概念があります。Both Objective-C and C# have the concept of properties to provide a high-level abstraction around accessor methods. Objective-C では、@property コンパイラ ディレクティブはアクセサー メソッドを効果的に生成するために使用されます。In Objective-C the @property compiler directive is used to effectively generate the accessor methods. これに対し、C# には、言語自体にプロパティのサポートが含まれます。In contrast, C# includes support for properties within the language itself. 次の例に示すように、C# プロパティは、バッキング フィールドにアクセスする長いスタイルを使用するか、より短い自動プロパティ構文を使用して実装できます。A C# property can be implemented using either a longer style that accesses a backing field, or using a shorter, automatic property syntax, as shown in the following examples:

// automatic property syntax
public string Name { get; set; }

// property implemented with a backing field
string address;
public string Address {
    get {
        // could add additional code here
        return address;
    }
    set {
        address = value;
    }
}

Static キーワードStatic Keyword

static キーワードの意味は、Objective-C と C# とで大きく異なります。The static keyword has very different meaning between Objective-C and C#. Objective-C の静的関数は、関数のスコープを現在のファイルに制限するために使用されます。In Objective-C static functions are used to limit the scope of a function to the current file. 一方、C# では、スコープは publicprivateinternal キーワードを通じて管理されます。In C# however, scope is maintained through the public, private and internal keywords.

Objective-C の変数に static キーワードが適用される場合、変数は関数呼び出し間でその値を保持します。When the static keyword is applied to a variable in Objective-C, the variable maintains its value across function calls.

C# にも static キーワードがあります。C# also has a static keyword. メソッドに適用する場合は、事実上、Objective-C での + 修飾子と同じ効果があります。When applied to a method, it effectively does the same thing that the + modifier does in Objective-C. つまり、クラス メソッドを作成します。Namely, it creates a class method. 同様に、フィールド、プロパティ、イベントなどの他のコンストラクトに適用される場合は、その型の任意のインスタンスではなく、そのコンストラクトを宣言した型の一部になります。Similarly, when applied to other constructs such as fields, properties and events, it makes those part of the type they are declared within rather than with any instance of that type. 静的クラスにすることもできます。その場合、クラスで定義されているすべてのメソッドが静的である必要があります。You can also make a static class, in which all the methods defined in the class must be static as well.

NSArray とリストの初期化NSArray vs. List Initialization

Objective-C には、NSArray で使用されるリテラル構文が含まれるようになり、初期化が簡単になっています。Objective-C now includes literal syntax for use with NSArray, making it easier to initialize. 一方、C# には List と呼ばれる "汎用的" で高度な型があります。このため、リストに保持する型は、リストを作成するコード (C++ のテンプレートのように) で提供できます。C# however has a richer type called a List which is generic, meaning the type the list holds can be provided by the code that creates the list (like templates in C++). さらに、リストでは、次に示すように自動初期化構文がサポートされます。Additionally, lists support auto-initialization syntax as shown below:

MyClass object1 = new MyClass ();
MyClass object2 = new MyClass ();
List<MyClass> myList = new List<MyClass>{ object1, object2 };

ブロックとラムダ式Blocks vs. Lambda Expressions

Objective-C は、"ブロック" を使用してクロージャを作成します。クロージャでは、そこで囲まれている状態を使用できる関数をインラインで作成できます。Objective-C uses blocks to create closures, where you can create a function inline that can make use of the state where it is enclosed. C# には、ラムダ式を使用する同様の概念があります。C# has a similar concept through the use of lambda expressions. C# では、ラムダ式は次のように => 演算子で作成されます。In C# lambda expressions are created with the => operator as shown below:

(args) => {
    //  implementation code
};

ラムダ式について詳しくは、Microsoft の C# プログラミング ガイドのページをご覧ください。For more information on lambda expressions, see Microsoft’s C# Programming Guide.

まとめSummary

この記事では、Objective-C と C# 間でさまざまな言語機能を比較しました。In this article a variety of language features were contrasted between Objective-C and C#. 場合によっては、ラムダ式とブロックや、拡張メソッドとカテゴリなど、両方の言語に存在する類似機能について説明しました。In some cases, it called out analogous features that exist between both languages, such as blocks to lambda expressions, and categories to extension methods. さらに、C# の名前空間と static キーワードの意味など、言語間で異なる部分を比較しました。Additionally, it contrasted places where the languages diverge, such as with namespaces in C# and the meaning of the static keyword.