.NET のツアーTour of .NET

.NET は、汎用的な開発プラットフォームです。.NET is a general purpose development platform. .NET には、複数のプラットフォームでのさまざまなシナリオを可能にする、複数のプログラミング言語、非同期および同時実行のプログラミング モデル、ネイティブな相互運用性のサポートなど、重要な機能がいくつかあります。It has several key features, such as support for multiple programming languages, asynchronous and concurrent programming models, and native interoperability, which enable a wide range of scenarios across multiple platforms.

この記事は、.NET のいくつかの重要な機能についてのガイド付きツアーです。This article offers a guided tour through some of the key features of the .NET. .NET アーキテクチャの構成要素とそれらの用途については、「.NET アーキテクチャ コンポーネント」をご覧ください。See the .NET Architectural Components topic to learn about the architectural pieces of .NET and what they're used for.

コード サンプルの実行方法How to run the code samples

コード サンプルを実行できるように開発環境を設定する方法については、はじめにをご覧ください。To learn how to set up a development environment to run the code samples, see the Getting Started topic. このページのコード サンプルをコピーして環境に貼り付けて実行します。Copy and paste code samples from this page into your environment to execute them.

プログラミング言語Programming languages

.NET は複数のプログラミング言語をサポートしています。.NET supports multiple programming languages. .NET 実装では、共通言語基盤 (CLI) が実装されています。CLI では特に、言語に依存しないランタイムと言語の相互運用性が指定されています。The .NET implementations implement the Common Language Infrastructure (CLI), which among other things specifies a language-independent runtime and language interoperability. つまり、任意の .NET 言語を選んで、.NET でアプリとサービスを作成します。This means that you choose any .NET language to build apps and services on .NET.

Microsoft が開発とサポートに力を注いでいる .NET 言語は、C#、F#、Visual Basic の 3 つです。Microsoft actively develops and supports three .NET languages: C#, F#, and Visual Basic.

  • C# はシンプル、強力、タイプセーフ、そしてオブジェクト指向でありながらも、C スタイル言語の表現力と簡潔さが維持されています。C# is simple, powerful, type-safe, and object-oriented, while retaining the expressiveness and elegance of C-style languages. C や類似の言語を使い慣れている人であれば、ほとんど問題なく C# に適応できます。Anyone familiar with C and similar languages finds few problems in adapting to C#. C# について詳しくは、「C# ガイド」 (C# ガイド) をご覧ください。Check out the C# Guide to learn more about C#.

  • F# はクロスプラットフォームの関数型プログラミング言語ですが、従来のオブジェクト指向および命令型プログラミングもサポートしています。F# is a cross-platform, functional-first programming language that also supports traditional object-oriented and imperative programming. F# について詳しくは、「F# ガイド」 (F# ガイド) をご覧ください。Check out the F# Guide to learn more about F#.

  • Visual Basic は、学習しやすい言語で、.NET 上で実行されるさまざまなアプリの構築に使用します。Visual Basic is an easy language to learn that you use to build a variety of apps that run on .NET. .NET 言語の中で Visual Basic の構文は通常の人間の言語に最も近いため、ソフトウェア開発の経験のないユーザーでも使いやすい言語です。Among the .NET languages, the syntax of Visual Basic is the closest to ordinary human language, often making it easier for people new to software development.

自動メモリ管理Automatic memory management

.NET は、ガベージ コレクション (GC) を使ってプログラムの自動メモリ管理を行います。.NET uses garbage collection (GC) to provide automatic memory management for programs. GC はメモリ管理に対する遅延アプローチで動作します。この場合、メモリの即時収集よりもアプリのスループットが優先されます。The GC operates on a lazy approach to memory management, preferring app throughput to the immediate collection of memory. .NET GC について詳しくは、「ガベージ コレクションの基礎」をご覧ください。To learn more about the .NET GC, check out Fundamentals of garbage collection (GC).

以下の 2 つの行はどちらもメモリを割り当てています。The following two lines both allocate memory:

var title = ".NET Primer";
var list = new List<string>();

ガベージ コレクターがスケジュールされた実行によってメモリを解放する際に割り当て解除が自動的に行われるため、メモリの割り当てを解除するための類似したキーワードはありません。There's no analogous keyword to de-allocate memory, as de-allocation happens automatically when the garbage collector reclaims the memory through its scheduled run.

ガベージ コレクターは、"メモリの安全性" の確保に役立つサービスの 1 つです。The garbage collector is one of the services that help ensure memory safety. 割り当てられているメモリのみにプログラムがアクセスする場合、そのプログラムはメモリ セーフです。A program is memory safe if it accesses only allocated memory. たとえば、ランタイムでは、配列の範囲を超えた割り当てられていないメモリにアプリがアクセスしていないことを確認します。For instance, the runtime ensures that an app doesn't access unallocated memory beyond the bounds of an array.

次の例では、メモリの安全性を確保するため、ランタイムにより IndexOutOfRangeException 例外がスローされます。In the following example, the runtime throws an IndexOutOfRangeException exception to enforce memory safety:

int[] numbers = new int[42];
int number = numbers[42]; // Will throw an exception (indexes are 0-based)

アンマネージ リソースの操作Working with unmanaged resources

一部のオブジェクトは、アンマネージ リソースを参照します。Some objects reference unmanaged resources. アンマネージ リソースは、.NET ランタイムで自動的に維持されないリソースです。Unmanaged resources are resources that aren't automatically maintained by the .NET runtime. たとえば、ファイル ハンドルは、アンマネージ リソースです。For example, a file handle is an unmanaged resource. FileStream オブジェクトはマネージ オブジェクトですが、アンマネージドのファイル ハンドルを参照します。A FileStream object is a managed object, but it references a file handle, which is unmanaged. FileStream の使用が終わったら、ファイル ハンドルを解放する必要があります。When you're done using the FileStream, you need to release the file handle.

.NET では、アンマネージ リソースを参照するオブジェクトは IDisposable インターフェイスを実装します。In .NET, objects that reference unmanaged resources implement the IDisposable interface. オブジェクトの使用が終わったら、すべてのアンマネージ リソースを解放する、オブジェクトの Dispose() メソッドを呼び出します。When you're done using the object, you call the object's Dispose() method, which is responsible for releasing any unmanaged resources. そのようなオブジェクトに対し、.NET 言語では次の例に示すように便利な using ステートメントが提供されています。.NET languages provide a convenient using statement for such objects, as shown in the following example:

using System.IO;

using (FileStream stream = GetFileStream(context))
{
    // Operations on the stream
}

using ブロックが完了すると、.NET ランタイムがファイル ハンドルを開放する stream オブジェクトの Dispose() メソッドを自動的に呼び出します。Once the using block completes, the .NET runtime automatically calls the stream object's Dispose() method, which releases the file handle. これは、例外によってコントロールがブロックを離れた場合にも行われます。The runtime also does this if an exception causes control to leave the block.

詳しくは、次のトピックをご覧ください。For more details, see the following topics:

タイプ セーフType safety

オブジェクトは特定の型のインスタンスです。An object is an instance of a specific type. 指定のオブジェクトが許可される操作は、その型から決まります。The only operations allowed for a given object are those of its type. Dog 型には JumpWagTail メソッドを含むことができますが、SumTotal メソッドを含むことはできません。A Dog type may have Jump and WagTail methods but not a SumTotal method. プログラムは、特定の型に属するメソッドのみを呼び出します。A program only calls the methods belonging to a given type. それ以外のどの呼び出しを行っても、コンパイル時エラーまたはランタイム例外が発生します (動的機能または object を使用した場合)。All other calls result in either a compile-time error or a run-time exception (in case of using dynamic features or object).

.NET 言語は、オブジェクト指向で、基本クラスと派生クラスの階層を含みます。.NET languages are object-oriented with hierarchies of base and derived classes. .NET ランタイムではオブジェクトの階層に応じたオブジェクトのキャストと呼び出しのみが許可されます。The .NET runtime only allows object casts and calls that align with the object hierarchy. .NET 言語で定義されているすべての型が、基本の Object 型から派生していることを覚えておいてください。Remember that every type defined in any .NET language derives from the base Object type.

Dog dog = AnimalShelter.AdoptDog(); // Returns a Dog type.
Pet pet = (Pet)dog; // Dog derives from Pet.
pet.ActCute();
Car car = (Car)dog; // Will throw - no relationship between Car and Dog.
object temp = (object)dog; // Legal - a Dog is an object.

タイプ セーフは、アクセサー キーワードの忠実性を保証することで、カプセル化の支援を行うためにも使用されます。Type safety is also used to help enforce encapsulation by guaranteeing the fidelity of the accessor keywords. アクセサー キーワードは、指定した型のメンバーへのアクセスを他のコードによって制御する成果物です。Accessor keywords are artifacts which control access to members of a given type by other code. これらは通常、その動作を管理するために使用される型に含まれる、さまざまな種類のデータに使用されます。These are usually used for various kinds of data within a type that are used to manage its behavior.

private Dog _nextDogToBeAdopted = AnimalShelter.AdoptDog()

C#、Visual Basic、F# は、ローカルな型推論をサポートします。C#, Visual Basic, and F# support local type inference. 型推論は、コンパイラが右側にある式から左側にある式の型を推論するという意味です。Type inference means that the compiler deduces the type of the expression on the left-hand side from the expression on the right-hand side. タイプ セーフの破損、または回避を意味するわけではありません。This doesn't mean that the type safety is broken or avoided. 結果の型には、推論されるすべてを含む厳密な型が含まれます。The resulting type does have a strong type with everything that implies. 前の例の dog を書き換えて型の推論を導入し、残りの部分はそのままとします。From the previous example, dog is rewritten to introduce type inference, and the remainder of the example is unchanged:

var dog = AnimalShelter.AdoptDog();
var pet = (Pet)dog;
pet.ActCute();
Car car = (Car)dog; // will throw - no relationship between Car and Dog
object temp = (object)dog; // legal - a Dog is an object
car = (Car)temp; // will throw - the runtime isn't fooled
car.Accelerate() // the dog won't like this, nor will the program get this far

F# は、C# や Visual Basic のメソッド ローカルな型推論よりさらに進んだ型推論機能を備えています。F# has even further type inference capabilities than the method-local type inference found in C# and Visual Basic. 詳しくは、「型の推定」 (型推論) をご覧ください。To learn more, see Type Inference.

デリゲートとラムダDelegates and lambdas

デリゲートは、メソッド シグネチャで表されます。A delegate is represented by a method signature. そのシグネチャを持つ任意のメソッドをデリゲートに割り当てることができます。割り当てたメソッドは、デリゲートが呼び出されると実行されます。Any method with that signature can be assigned to the delegate and is executed when the delegate is invoked.

デリゲートは、C++ の関数ポインターに似ています。ただし、タイプ セーフであるという点は異なります。Delegates are like C++ function pointers except that they're type safe. CLR 型システム内で接続されていないメソッドの一種です。They're a kind of disconnected method within the CLR type system. 通常のメソッドはクラスに接続されており、静的な、またはインスタンスが呼び出す規則によってのみ直接呼び出すことができます。Regular methods are attached to a class and are only directly callable through static or instance calling conventions.

.NET では、デリゲートはイベント ハンドラー (非同期の操作を定義するとき) やラムダ式 (LINQ の基軸である) でよく使用されます。In .NET, delegates are commonly used in event handlers, in defining asynchronous operations, and in lambda expressions, which are a cornerstone of LINQ. 詳細について、「デリゲートとラムダ」を参照してください。Learn more in the Delegates and lambdas topic.

ジェネリックGenerics

ジェネリックを使用することで、プログラマーがクラスを設計する際に "型パラメーター" を導入することができ、これによってクライアント コード (その型のユーザー) が型パラメーターの代わりに使用する正確な型を指定できるようになります。Generics allow the programmer to introduce a type parameter when designing their classes that allows the client code (the users of the type) to specify the exact type to use in place of the type parameter.

ジェネリックは、プログラマが汎用的なデータ構造を実装するために追加されました。Generics were added to help programmers implement generic data structures. それ以前は、List などの型をジェネリックにするには、object 型の要素を使用する必要がありました。Before their arrival, in order for a type such as the List type to be generic, it would have to work with elements that were of type object. これにより、軽微なランタイム エラーの可能性があることは言うまでもなく、パフォーマンスやセマンティックのさまざまな問題が発生することがありました。This had various performance and semantic problems, along with possible subtle run-time errors. 一般的なランタイム エラーは、たとえば、データ構造に整数と文字列の両方が含まれる場合に、リストのメンバーの処理中に InvalidCastException がスローされるということです。A common run-time error is when a data structure contains, for example, both integers and strings, and an InvalidCastException is thrown while processing the list's members.

以下のサンプルに、List<T> 型のインスタンスを使用して実行される基本的なプログラムを示します。The following sample shows a basic program running using an instance of List<T> types:

using System;
using System.Collections.Generic;

namespace GenericsSampleShort
{
    public static void Main(string[] args)
    {
        // List<string> is the client way of specifying the actual type for the type parameter T
        List<string> listOfStrings = new List<string> { "First", "Second", "Third" };

        // listOfStrings can accept only strings, both on read and write.
        listOfStrings.Add("Fourth");

        // Below will throw a compile-time error, since the type parameter
        // specifies this list as containing only strings.
        listOfStrings.Add(1);
    }
}

詳細については、トピック「ジェネリック型 (ジェネリック) の概要」を参照してください。For more information, see the Generic types (Generics) overview topic.

非同期プログラミングAsync programming

非同期プログラミングは、ランタイムでの非同期サポート、フレームワーク ライブラリ、.NET 言語構成要素が含まれる、.NET のファースト クラスの概念です。Async programming is a first-class concept within .NET with async support in the runtime, framework libraries, and .NET language constructs. 内部は、オペレーティング システムを利用して可能な限り効率的に I/O バウンドなジョブを実行する、(Task などの) オブジェクトに基づいています。Internally, they're based on objects (such as Task), which take advantage of the operating system to perform I/O-bound jobs as efficiently as possible.

.NET の非同期プログラミングの詳細を理解するには、最初にトピック「非同期の概要」を参照してください。To learn more about async programming in .NET, start with the Async overview topic.

統合言語クエリ (LINQ)Language Integrated Query (LINQ)

LINQ は、データ操作のための単純な宣言型コードを記述できる、C# および Visual Basic の強力な一連の機能です。LINQ is a powerful set of features for C# and Visual Basic that allow you to write simple, declarative code for operating on data. データは (メモリ内オブジェクト、SQL データベース、XML ドキュメントなどの) さまざまな形式にすることができますが、記述する LINQ コードは通常、どのデータ ソースでも違いがないように見えます。The data can be in many forms (such as in-memory objects, a SQL database, or an XML document), but the LINQ code you write typically doesn't differ by data source.

詳細および一部のサンプルについては、LINQ (統合言語クエリ) の概要に関する記事を参照してください。To learn more and see some samples, see the LINQ (Language Integrated Query) overview article.

ネイティブ相互運用性Native interoperability

どのオペレーティング システムにも、システム サービスを提供するアプリケーション プログラミング インターフェイス (API) が含まれています。Every operating system includes an application programming interface (API) that provides system services. .NET には、その API を呼び出すためのいくつかの方法が用意されています。.NET provides several ways to call those APIs.

ネイティブの相互運用を行う主な方法が、"プラットフォーム呼び出し" (略して P/Invoke) を使用するものです。これは、Linux および Windows のプラットフォームに渡ってサポートされています。The main way to do native interoperability is via "platform invoke" or P/Invoke for short, which is supported across Linux and Windows platforms. Windows 限定でネイティブの相互運用を行う方法が "COM 相互運用" です。これは、マネージド コードで COM コンポーネントを操作する場合に使用します。A Windows-only way of doing native interoperability is known as "COM interop," which is used to work with COM components in managed code. これは、P/Invoke インフラストラクチャ上に構築されますが、動作は少し異なります。It's built on top of the P/Invoke infrastructure, but it works in subtly different ways.

Java および Objective-C に対する Mono (つまり Xamarin) の相互運用性サポートの多くが同じようにして構築されています。つまり、同じ原則を使用しているということです。Most of Mono's (and thus Xamarin's) interoperability support for Java and Objective-C are built similarly, that is, they use the same principles.

ネイティブ相互運用性の詳細については、記事「ネイティブ相互運用性」を参照してください。For more information about native interoperability, see the Native interoperability article.

アンセーフ コードUnsafe code

言語サポートに応じて、CLR の unsafe コードによって、ネイティブ メモリにアクセスしたりポインターの算術演算を実行したりできるようになります。Depending on language support, the CLR lets you access native memory and do pointer arithmetic via unsafe code. この操作は、特定のアルゴリズムおよびシステム相互運用性のために必要です。These operations are needed for certain algorithms and system interoperability. アンセーフ コードの使用は強力ですが、システム API との相互運用を行ったり、最も効率的なアルゴリズムを実装したりする必要がなければ、推奨されません。Although powerful, use of unsafe code is discouraged unless it's necessary to interop with system APIs or implement the most efficient algorithm. アンセーフ コードは、環境が異なると同じように実行されない可能性があり、さらにガベージ コレクターとタイプ セーフの利点が得られない場合があります。Unsafe code may not execute the same way in different environments and also loses the benefits of a garbage collector and type safety. 可能な限りアンセーフ コードのみに制限し、そのコードを徹底的にテストすることをお勧めします。It's recommended to confine and centralize unsafe code as much as possible and test that code thoroughly.

StringBuilder クラスから ToString() メソッドを変更した例を次に示します。The following example is a modified version of the ToString() method from the StringBuilder class. 次のように unsafe コードを使用してメモリのチャンクを直接移動して、アルゴリズムを効率的に実装する方法を示しています。It illustrates how using unsafe code can efficiently implement an algorithm by moving around chunks of memory directly:

public override String ToString()
{
    if (Length == 0)
        return String.Empty;

    string ret = string.FastAllocateString(Length);
    StringBuilder chunk = this;
    unsafe
    {
        fixed (char* destinationPtr = ret)
        {
            do
            {
                if (chunk.m_ChunkLength > 0)
                {
                    // Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this)
                    char[] sourceArray = chunk.m_ChunkChars;
                    int chunkOffset = chunk.m_ChunkOffset;
                    int chunkLength = chunk.m_ChunkLength;

                    // Check that we will not overrun our boundaries.
                    if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
                    {
                        fixed (char* sourcePtr = sourceArray)
                            string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                    }
                }
                chunk = chunk.m_ChunkPrevious;
            } while (chunk != null);
        }
    }
    return ret;
}

次の手順Next steps

C# の機能については、「C# のツアー」をご覧ください。If you're interested in a tour of C# features, check out Tour of C#.

F# の機能については、「F# のツアー」をご覧ください。If you're interested in a tour of F# features, see Tour of F#.

独自のコードの記述を開始する場合は、「Getting Started」 (はじめに) をご覧ください。If you want to get started with writing code of your own, visit Getting Started.

.NET の重要なコンポーネントについては、「.NET アーキテクチャ コンポーネント」をご覧ください。To learn about important components of .NET, check out .NET Architectural Components.