はじめにIntroduction

C# ("シー シャープ" と読みます) は、シンプルで最新のタイプ セーフなオブジェクト指向のプログラミング言語です。C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C# には、C ファミリの言語でルートがあり、C、C++、Java プログラマーにすぐに慣れることができます。C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C# は、ECMA International by ecma-334 _ STANDARD、ISO/iec By _ iso/iec 23270 標準として標準化されています。C# is standardized by ECMA International as the ECMA-334 _ standard and by ISO/IEC as the _ ISO/IEC 23270 standard. Microsoft の .NET Framework 用 C# コンパイラは、これらの標準の両方の準拠した実装です。Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C# はオブジェクト指向言語ですが、C# にはさらに "コンポーネント指向" プログラミングのサポートが含まれています。C# is an object-oriented language, but C# further includes support for component-oriented programming. 最近のソフトウェア設計では、機能を自己完結型および自己記述型パッケージの形式にしたソフトウェア コンポーネントをますます使用するようになっています。Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. そのようなコンポーネントの鍵となるのは、プロパティ、メソッド、イベントを使用してプログラミング モデルを表すこと、コンポーネントについての宣言的な情報を提供する属性があること、独自のドキュメントが組み込まれていることです。Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C# には、これらの概念を直接サポートする言語構成要素が用意されています。 C# は、ソフトウェアコンポーネントを作成して使用するための非常に自然な言語です。C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

堅牢で持続性のあるアプリケーションの構築に役立つ C# の機能がいくつかあります。 ガベージコレクション _ は、未使用のオブジェクトによって占有されているメモリを自動的に解放します。 _例外処理*_ は、エラーの検出と回復を行うための構造化された拡張可能なアプローチを提供します。また、言語の 型セーフ な * 設計により、初期化されていない変数からの読み取り、配列の境界外のインデックス作成、またはチェックを行わない型キャストの実行が不可能になります。Several C# features aid in the construction of robust and durable applications: Garbage collection _ automatically reclaims memory occupied by unused objects; _exception handling_ provides a structured and extensible approach to error detection and recovery; and the _ type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

C# は "統合型システム" を採用しています。C# has a unified type system. intdouble などのプリミティブ型を含めた C# のすべての型は、ルートとなる 1 つの object 型から派生しています。All C# types, including primitive types such as int and double, inherit from a single root object type. したがって、すべての型が一般的な操作のセットを共有し、すべての型の値を一貫した方法で格納、転送、操作することができます。Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. さらに、C# はユーザー定義の参照型と値型の両方をサポートしているため、オブジェクトを動的に割り当てることも、軽量の構造体をインラインで格納することもできます。Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

C# のプログラムとライブラリが互換性を保ちながら時間とともに進化できるように、C# の設計では "バージョン管理" に大きな重点が置かれています。To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. 多くのプログラミング言語は、この問題にほとんど注意を払っていません。その結果、それらの言語で書かれたプログラムは、依存するライブラリの新しいバージョンが導入されたときに必要以上に頻繁に中断されてしまいます。Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. C# の設計でバージョン管理の考慮の影響を直接受けている側面として、別個の virtual 修飾子と override 修飾子、メソッドのオーバーロードの解決規則、明示的なインターフェイス メンバー宣言のサポートなどがあります。Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

この章の残りの部分では、C# 言語の重要な機能について説明します。The rest of this chapter describes the essential features of the C# language. 後の章では、ルールと例外について詳しく説明し、場合によっては数学的に説明しますが、この章では、完全性を犠牲にし、簡潔さを重視しています。Although later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. この目的は、初期のプログラムの記述と後の章の読み取りを容易にする言語の概要をリーダーに提供することです。The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters.

Hello worldHello world

"Hello, World" は、プログラミング言語を紹介するために伝統的に使用されているプログラムです。The "Hello, World" program is traditionally used to introduce a programming language. これを C# で記述すると次のようになります。Here it is in C#:

using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}

通常、C# のソース ファイルのファイル拡張子は .cs です。C# source files typically have the file extension .cs. "Hello, World" プログラムがファイルに格納されていると仮定すると、 hello.cs コマンドラインを使用して、Microsoft C# コンパイラでプログラムをコンパイルできます。Assuming that the "Hello, World" program is stored in the file hello.cs, the program can be compiled with the Microsoft C# compiler using the command line

csc hello.cs

これにより、という名前の実行可能アセンブリが生成さ hello.exe れます。which produces an executable assembly named hello.exe. このアプリケーションの実行時に生成される出力は次のようになります。The output produced by this application when it is run is

Hello, World

"Hello, World" プログラムは System 名前空間を参照する using ディレクティブで始まります。The "Hello, World" program starts with a using directive that references the System namespace. 名前空間は、C# のプログラムとライブラリを階層的に整理するための手段です。Namespaces provide a hierarchical means of organizing C# programs and libraries. 名前空間には、型と他の名前空間が含まれます。たとえば、System 名前空間には多数の型 (プログラムで参照される Console クラスなど) と、他の多数の名前空間 (IOCollections など) が含まれます。Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. 特定の名前空間を参照する using ディレクティブを使用すると、その名前空間のメンバーである型を修飾せずに使用できます。A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. using ディレクティブにより、プログラムで Console.WriteLineSystem.Console.WriteLine の省略形として使用できます。Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

"Hello, World" プログラムで宣言された Hello クラスにはメンバーが 1 つあります。Main という名前のメソッドです。The Hello class declared by the "Hello, World" program has a single member, the method named Main. Main メソッドは static 修飾子を使用して宣言されています。The Main method is declared with the static modifier. インスタンス メソッドが this で囲んだ特定のオブジェクト インスタンスを参照できるのに対し、静的メソッドは特定のオブジェクトを参照せずに機能します。While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. 規則により、Main という名前の静的メソッドはプログラムのエントリ ポイントとして使用されます。By convention, a static method named Main serves as the entry point of a program.

プログラムの出力は、System 名前空間にある Console クラスの WriteLine メソッドによって生成されます。The output of the program is produced by the WriteLine method of the Console class in the System namespace. このクラスは、既定では Microsoft C# コンパイラによって自動的に参照される .NET Framework クラスライブラリによって提供されます。This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. C# 自体には、個別のランタイムライブラリがないことに注意してください。Note that C# itself does not have a separate runtime library. 代わりに、.NET Framework は C# のランタイムライブラリです。Instead, the .NET Framework is the runtime library of C#.

プログラムの構造Program structure

C# の主要な組織概念は、プログラム _ _、名前空間_、 __、 _メンバー_、および _アセンブリ*_ です。The key organizational concepts in C# are programs _, _namespaces_, _types_, _members_, and _assemblies*_. C# プログラムは、1 つまたは複数のソース ファイルで構成されています。C# programs consist of one or more source files. プログラムは型を宣言します。型にはメンバーが含まれていて、複数の名前空間に編成することができます。Programs declare types, which contain members and can be organized into namespaces. 型の例には、クラスおよびインターフェイスがあります。Classes and interfaces are examples of types. メンバーの例には、フィールド、メソッド、プロパティ、およびイベントがあります。Fields, methods, properties, and events are examples of members. C# プログラムはコンパイルされると、物理的にアセンブリにパッケージ化されます。When C# programs are compiled, they are physically packaged into assemblies. アセンブリには、通常、 .exe .dll *アプリケーション* と _ ライブラリ * のどちらを実装するかに応じて、ファイル拡張子またはが含まれます。Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or _*libraries**.

例を示します。The example

using System;

namespace Acme.Collections
{
    public class Stack
    {
        Entry top;

        public void Push(object data) {
            top = new Entry(top, data);
        }

        public object Pop() {
            if (top == null) throw new InvalidOperationException();
            object result = top.data;
            top = top.next;
            return result;
        }

        class Entry
        {
            public Entry next;
            public object data;
    
            public Entry(Entry next, object data) {
                this.next = next;
                this.data = data;
            }
        }
    }
}

という名前空間で、という名前のクラスを宣言 Stack Acme.Collections します。declares a class named Stack in a namespace called Acme.Collections. このクラスの完全修飾名は Acme.Collections.Stack です。The fully qualified name of this class is Acme.Collections.Stack. このクラスには複数のメンバーが含まれています: top という名前のフィールドが 1 つ、PushPop という名前のメソッドが合わせて 2 つ、そして Entry という名前の入れ子になったクラスです。The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. Entry クラスにはさらに、3 つのメンバーが含まれています: next という名前のフィールド、data という名前のフィールド、およびコンストラクターです。The Entry class further contains three members: a field named next, a field named data, and a constructor. 例のソース コードが acme.cs のファイルに保存されていることを前提に、次のコマンド ラインをご覧ください。Assuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

このコマンド ラインは例をライブラリ (Main エントリ ポイントがないコード) としてコンパイルし、acme.dll という名前のアセンブリを生成します。compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

アセンブリには、*中間言語 _ (IL) 命令の形式の実行可能コードと、_ metadata * 形式のシンボリック情報が含まれています。Assemblies contain executable code in the form of Intermediate Language _ (IL) instructions, and symbolic information in the form of _metadata**. アセンブリの IL コードは実行前に、.NET 共通言語ランタイムの Just-In-Time (JIT) コンパイラによって、プロセッサ固有のコードに自動的に変換されます。Before it is executed, the IL code in an assembly is automatically converted to processor-specific code by the Just-In-Time (JIT) compiler of .NET Common Language Runtime.

アセンブリはコードとメタデータの両方を含む自己記述的な機能的単位であるため、#include ディレクティブおよびヘッダー ファイルが C# に含まれている必要はありません。Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. 特定のアセンブリに含まれているパブリックの型とメンバーは、単にプログラムのコンパイル中にそのアセンブリを参照することにより、C# プログラムで利用可能になります。The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. たとえば、このプログラムでは acme.dll アセンブリの Acme.Collections.Stack クラスを使用しています。For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Test
{
    static void Main() {
        Stack s = new Stack();
        s.Push(1);
        s.Push(10);
        s.Push(100);
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
    }
}

プログラムがファイルに格納されている場合 test.cs 、をコンパイルするときに、 test.cs acme.dll コンパイラのオプションを使用してアセンブリを参照でき /r ます。If the program is stored in the file test.cs, when test.cs is compiled, the acme.dll assembly can be referenced using the compiler's /r option:

csc /r:acme.dll test.cs

これにより test.exe という名前の実行可能なアセンブリが作成され、これが実行された場合に、次の出力が生成されます。This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C# では、プログラムのソース テキストを複数のソース ファイルに保存することができます。C# permits the source text of a program to be stored in several source files. 複数ファイルの C# プログラムがコンパイルされると、ソース ファイルはすべて同時に処理され、ソース ファイルは自由に相互を参照できるようになります。概念的には、ソース ファイルが処理される前に、すべて 1 つの大きいファイルに連結されるようなものです。When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. C# では事前宣言をする必要がありません。ごく一部の例外を除いて、宣言の順序は重要でないためです。Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C# ではソース ファイルがパブリック型 1 つのみの宣言に制限されません。また、ソース ファイルの名前がソース ファイルで宣言された型に一致する必要もありません。C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.

型と変数Types and variables

C# の型には、*値型 _ と _ 参照型 * の2種類があります。There are two kinds of types in C#: value types _ and _reference types**. 値型の変数が直接データを格納するのに対して、参照型の変数はデータへの参照を格納し、後者はオブジェクトとして知られています。Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. 参照型を使用すると 2 つの変数が同じオブジェクトを参照できるため、1 つの変数に対する演算によって、もう一方の変数によって参照されるオブジェクトに影響を与えることができます。With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. 値型の場合、各変数が独自のデータ コピーを保持し、1 つの変数に対する演算で別の変数に影響を与えることはできません (refout のパラメーターの変数の場合を除く)。With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).

C# の値型はさらに、単純型 _、 _列挙型_、 _構造体型_、および _null 許容型_ に分割され、c# の参照型はさらに、 _クラス型_、 _インターフェイス型_、 _配列型*、および _ *デリゲート型* * に分割されます。C#'s value types are further divided into simple types _, _enum types*, struct types, and nullable types, and C#'s reference types are further divided into class types, interface types, array types, and _*delegate types**.

次の表は、C# の型システムの概要を示しています。The following table provides an overview of C#'s type system.

カテゴリCategory 説明Description
値型Value types 単純型Simple types 符号付きの整数: sbyteshortintlongSigned integral: sbyte, short, int, long
符号なしの整数: byteushortuintulongUnsigned integral: byte, ushort, uint, ulong
Unicode 文字: charUnicode characters: char
IEEE 浮動小数点: floatdoubleIEEE floating point: float, double
高精度の 10 進数: decimalHigh-precision decimal: decimal
ブール値: boolBoolean: bool
列挙型Enum types enum E {...} 形式のユーザー定義型User-defined types of the form enum E {...}
構造体の型Struct types struct S {...} 形式のユーザー定義型User-defined types of the form struct S {...}
null 許容型Nullable types null 値を持つその他すべての値型の拡張子Extensions of all other value types with a null value
参照型Reference types クラスの種類Class types その他すべての型の最終的な基底クラス: objectUltimate base class of all other types: object
Unicode 文字列: stringUnicode strings: string
class C {...} 形式のユーザー定義型User-defined types of the form class C {...}
インターフェイス型Interface types interface I {...} 形式のユーザー定義型User-defined types of the form interface I {...}
配列型Array types 1 次元または多次元、たとえば int[] および int[,]Single- and multi-dimensional, for example, int[] and int[,]
デリゲート型Delegate types フォームのユーザー定義型 (例: delegate int D(...)User-defined types of the form e.g. delegate int D(...)

8 つの整数型は、符号付きまたは符号なしの形式で、8 ビット、16 ビット、32 ビットおよび 64 ビットの値をサポートします。The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

2つの浮動小数点型 ( float と) は、 double 32 ビットの単精度と64ビットの倍精度の IEEE 754 形式を使用して表されます。The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

decimal 型は 128 ビットのデータ型で、財務や通貨の計算に適しています。The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C# の bool 型は、ブール値 (またはの値) を表すために使用され true false ます。C#'s bool type is used to represent boolean values—values that are either true or false.

C# における文字および文字列の処理では、Unicode エンコーディングを使用します。Character and string processing in C# uses Unicode encoding. char 型は UTF-16 コード単位を表し、string 型は一連の UTF-16 コード単位を表します。The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

次の表は、C# の数値型をまとめたものです。The following table summarizes C#'s numeric types.

カテゴリCategory BitsBits TypeType 範囲/精度Range/Precision
符号付き整数Signed integral 88 sbyte -128... 127-128...127
1616 short -32768... 32、767-32,768...32,767
3232 int -2147483648... 2、147、483、647-2,147,483,648...2,147,483,647
6464 long -9223372036854775808... 9、223、372、036、854、775、807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
符号なしの整数Unsigned integral 88 byte 0... 2550...255
1616 ushort 0... 65、5350...65,535
3232 uint 0... 4、294、967、2950...4,294,967,295
6464 ulong 0... 18、446、744、073、709、551、6150...18,446,744,073,709,551,615
浮動小数点Floating point 3232 float 1.5 × 10 ^ − 45 ~ 3.4 × 10 ^ 38、7桁の有効桁数1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5.0 × 10 ^ − 324 ~ 1.7 × 10 ^ 308、15桁の有効桁数5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1.0 × 10 ^ −28から7.9 × 10 ^ 28、28桁の有効桁数1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

C# プログラムでは 型宣言 を使用して新しい型を作成します。C# programs use type declarations to create new types. 型宣言は、新しい型の名前とメンバーを指定します。A type declaration specifies the name and the members of the new type. C# の型カテゴリのうち 5 つはユーザー定義が可能です。クラス型、構造体型、インターフェイス型、列挙型、そしてデリゲート型です。Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

クラス型は、データメンバー (フィールド) と関数メンバー (メソッド、プロパティなど) を含むデータ構造を定義します。A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). クラス型では、単一継承とポリモーフィズムをサポートします。このメカニズムによって派生クラスが基底クラスを拡張して特殊化できます。Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

構造体型は、データメンバーと関数メンバーを持つ構造体を表すという点で、クラス型に似ています。A struct type is similar to a class type in that it represents a structure with data members and function members. ただし、クラスとは異なり、構造体は値型であり、ヒープ割り当ては必要ありません。However, unlike classes, structs are value types and do not require heap allocation. 構造体型はユーザー指定の継承をサポートせず、すべての構造体型は暗黙的に object 型を継承します。Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

インターフェイス型は、パブリック関数メンバーの名前付きセットとしてコントラクトを定義します。An interface type defines a contract as a named set of public function members. インターフェイスを実装するクラスまたは構造体は、インターフェイスの関数メンバーの実装を提供する必要があります。A class or struct that implements an interface must provide implementations of the interface's function members. インターフェイスは複数の基本インターフェイスから継承でき、クラスまたは構造体は複数のインターフェイスを実装できます。An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

"デリゲート型" は、特定のパラメーター リストおよび戻り値の型を持つメソッドへの参照を表します。A delegate type represents references to methods with a particular parameter list and return type. デリゲートを使用すれば、変数に割り当ててパラメーターとして渡すことのできるエンティティとして、メソッドを処理できます。Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. デリゲートはまた、他のいくつかの言語にみられる関数ポインターの概念に似ていますが、関数ポインターとは異なり、デリゲートはオブジェクト指向でタイプ セーフです。Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

クラス、構造体、インターフェイス、およびデリゲート型はすべてジェネリックをサポートし、他の型でパラメーター化することができます。Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

列挙型は、名前付き定数を持つ別個の型です。An enum type is a distinct type with named constants. すべての列挙型には基になる型があり、これは8つの整数型のいずれかである必要があります。Every enum type has an underlying type, which must be one of the eight integral types. 列挙型の値のセットは、基になる型の値のセットと同じです。The set of values of an enum type is the same as the set of values of the underlying type.

C# は、あらゆる型の 1 次元および多次元の配列をサポートしています。C# supports single- and multi-dimensional arrays of any type. 上記の型とは異なり、配列型は使用前に宣言する必要がありません。Unlike the types listed above, array types do not have to be declared before they can be used. 代わりに配列型は、角かっこで囲んだ型名を後に付けることにより構成されます。Instead, array types are constructed by following a type name with square brackets. たとえば、 int[] はの1次元配列で、は int の2次元配列であり、 int[,] int int[][] はの1次元配列の1次元配列です intFor example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays of int.

Null 許容型は、使用する前に宣言する必要もありません。Nullable types also do not have to be declared before they can be used. Null 非許容の値型ごとに、 T 対応する null 許容型があり T? ます。これには、追加の値を保持でき null ます。For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. たとえば、 int? は、任意の32ビット整数または値を保持できる型です nullFor instance, int? is a type that can hold any 32 bit integer or the value null.

C# の型システムは、任意の型の値をオブジェクトとして扱うことができるように統合されています。C#'s type system is unified such that a value of any type can be treated as an object. C# における型はすべて、直接的または間接的に object クラス型から派生し、object はすべての型の究極の基底クラスです。Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. 参照型の値は、値を単純に object 型としてみなすことによってオブジェクトとして扱われます。Values of reference types are treated as objects simply by viewing the values as type object. 値型の値は、ボックス 化 _ および _ ボックス化解除 操作を実行することで、オブジェクトとして扱われます。Values of value types are treated as objects by performing boxing _ and _ unboxing operations. 次の例では、int 値は object 値に変換され、また int に戻されます。In the following example, an int value is converted to object and back again to int.

using System;

class Test
{
    static void Main() {
        int i = 123;
        object o = i;          // Boxing
        int j = (int)o;        // Unboxing
    }
}

値型の値を型に変換すると、 object オブジェクトインスタンス ("box" とも呼ばれます) が値を保持するために割り当てられ、値がそのボックスにコピーされます。When a value of a value type is converted to type object, an object instance, also called a "box," is allocated to hold the value, and the value is copied into that box. 逆に、 object 参照が値型にキャストされると、参照先のオブジェクトが正しい値の型のボックスであることがチェックされます。チェックに成功した場合は、ボックス内の値がコピーされます。Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

C# の統合型システムは、値型が "オンデマンド" でオブジェクトになる可能性があることを意味します。C#'s unified type system effectively means that value types can become objects "on demand." こうした統一性があるため、object 型を使用する汎用的なライブラリは、参照型と値型の両方で使用できます。Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

C# には、フィールド、配列要素、ローカル変数、パラメーターなどの、いくつかの種類の 変数 があります。There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. 変数はストレージの場所を表し、すべての変数には、次の表に示すように、変数に格納できる値を決定する型があります。Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown by the following table.

変数の種類Type of Variable 使用可能な内容Possible Contents
null 非許容値型Non-nullable value type 型そのものの値A value of that exact type
null 許容値型Nullable value type Null 値またはその正確な型の値A null value or a value of that exact type
object Null 参照、任意の参照型のオブジェクトへの参照、または任意の値型のボックス化された値への参照A null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
クラス型Class type Null 参照、そのクラス型のインスタンスへの参照、またはそのクラス型から派生したクラスのインスタンスへの参照A null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
インターフェイスの型Interface type Null 参照、そのインターフェイス型を実装するクラス型のインスタンスへの参照、またはそのインターフェイス型を実装する値型のボックス化された値への参照A null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
配列型Array type Null 参照、その配列型のインスタンスへの参照、または互換性のある配列型のインスタンスへの参照A null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
デリゲート型Delegate type Null 参照、またはそのデリゲート型のインスタンスへの参照A null reference or a reference to an instance of that delegate type

Expressions

_ は、 _オペランド_ と _演算子*_ から構築されます。Expressions _ are constructed from _operands_ and _operators*_. 式の演算子は、オペランドに適用する演算を表します。The operators of an expression indicate which operations to apply to the operands. 演算子の例として、+-_/、および new などがあります。Examples of operators include +, -, _, /, and new. オペランドの例としては、リテラル、フィールド、ローカル変数、式などがあります。Examples of operands include literals, fields, local variables, and expressions.

式に複数の演算子が含まれている場合、演算子の *優先順位 は、個々の演算子が評価される順序を制御します。When an expression contains multiple operators, the *precedence _ of the operators controls the order in which the individual operators are evaluated. たとえば、式 x + y _ z の評価は x + (y * z) ですが、これは * 演算子が + 演算子より高い優先順位だからです。For example, the expression x + y _ z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

ほとんどの演算子は オーバーロード できます。Most operators can be overloaded. 演算子をオーバーロードすると、ユーザー定義演算子の実装を、1 つまたは両方のオペランドがユーザー定義のクラスまたは構造体型である演算子に指定することができます。Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.

次の表は、演算子のカテゴリを優先順位の高い順に一覧表示する C# の演算子をまとめたものです。The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. 同じカテゴリ内の演算子の優先順位は同じです。Operators in the same category have equal precedence.

カテゴリCategory [式]Expression 説明Description
プライマリPrimary x.m メンバー アクセス。Member access
x(...) メソッドおよびデリゲートの呼び出し。Method and delegate invocation
x[...] 配列アクセスおよびインデクサー アクセス。Array and indexer access
x++ 後置インクリメント。Post-increment
x-- 後置デクリメント。Post-decrement
new T(...) オブジェクトおよびデリゲートの作成。Object and delegate creation
new T(...){...} 初期化子を使用したオブジェクトの作成Object creation with initializer
new {...} 匿名オブジェクト初期化子Anonymous object initializer
new T[...] 配列の作成Array creation
typeof(T) TSystem.Type オブジェクトの取得Obtain System.Type object for T
checked(x) checked コンテキストで式を評価します。Evaluate expression in checked context
unchecked(x) unchecked コンテキストで式を評価します。Evaluate expression in unchecked context
default(T) T 型の既定値の取得Obtain default value of type T
delegate {...} 匿名関数 (匿名メソッド)。Anonymous function (anonymous method)
単項Unary +x IDIdentity
-x 否定Negation
!x 論理否定Logical negation
~x ビットごとの否定。Bitwise negation
++x 前置インクリメント。Pre-increment
--x 前置デクリメント。Pre-decrement
(T)x x を明示的に T 型に変換Explicitly convert x to type T
await x x が完了するのを非同期的に待つAsynchronously wait for x to complete
乗法Multiplicative x * y 乗算Multiplication
x / y 除算Division
x % y 剰余Remainder
加法Additive x + y 加算、文字列の連結、デリゲートの組み合わせ。Addition, string concatenation, delegate combination
x - y 減算、デリゲートの削除。Subtraction, delegate removal
ShiftShift x << y 左シフト。Shift left
x >> y 右シフト。Shift right
関係式と型検査Relational and type testing x < y より小さいLess than
x > y より大きいGreater than
x <= y 以下Less than or equal
x >= y 以上Greater than or equal
x is T xT であれば true を、そうでなければ false を返すReturn true if x is a T, false otherwise
x as T T として型指定された x か、xT でない場合は null を返すReturn x typed as T, or null if x is not a T
等価比較Equality x == y 等しいEqual
x != y 等しくないNot equal
論理積Logical AND x & y 整数のビットごとの AND、ブール型の論理 ANDInteger bitwise AND, boolean logical AND
論理 XORLogical XOR x ^ y 整数のビットごとの XOR、ブール型の論理 XOR。Integer bitwise XOR, boolean logical XOR
論理和Logical OR x | y 整数のビットごとの OR、ブール型の論理 OR。Integer bitwise OR, boolean logical OR
条件 ANDConditional AND x && y y x がの場合にのみ評価されます。trueEvaluates y only if x is true
条件 ORConditional OR x || y y x がの場合にのみ評価されます。falseEvaluates y only if x is false
Null 合体演算子Null coalescing x ?? y y x がの場合は nullx それ以外の場合はに評価されます。Evaluates to y if x is null, to x otherwise
条件付きConditional x ? y : z xtrue の場合は y を、xfalse の場合は z を評価するEvaluates y if x is true, z if x is false
代入または匿名関数Assignment or anonymous function x = y 割り当てAssignment
x op= y 複合代入。サポートされて *= /= %= += -= <<= いる >>= 演算子 &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y 匿名関数 (ラムダ式)Anonymous function (lambda expression)

ステートメントStatements

プログラムの処理は、"ステートメント" を使用して表されます。The actions of a program are expressed using statements. C# はさまざまな種類のステートメントをサポートしており、その多くは埋め込みステートメントとして定義されています。C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

"ブロック" を使用すると、1 つのステートメントしか使用できないコンテキストで複数のステートメントを記述できます。A block permits multiple statements to be written in contexts where a single statement is allowed. ブロックは、区切り記号 {} の間に記述されたステートメントのリストから成ります。A block consists of a list of statements written between the delimiters { and }.

"宣言ステートメント" は、ローカル変数および定数の宣言に使用します。Declaration statements are used to declare local variables and constants.

"式ステートメント" は、式の評価に使用します。Expression statements are used to evaluate expressions. ステートメントとして使用できる式には、メソッドの呼び出し、演算子を使用したオブジェクト new の割り当て、演算子と = 複合代入演算子、および演算子と await 式を使用した加算およびデクリメント演算が含まれ ++ -- ます。Expressions that can be used as statements include method invocations, object allocations using the new operator, assignments using = and the compound assignment operators, increment and decrement operations using the ++ and -- operators and await expressions.

"選択ステートメント" は、式の値に基づいて、実行できる多数のステートメントから 1 つを選択するために使用します。Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. このグループには if および switch ステートメントが含まれます。In this group are the if and switch statements.

繰り返し ステートメント は、埋め込みステートメントを繰り返し実行するために使用されます。Iteration statements are used to repeatedly execute an embedded statement. このグループには、whiledofor、および foreach ステートメントが含まれます。In this group are the while, do, for, and foreach statements.

"ジャンプ ステートメント" は、制御を移すために使用します。Jump statements are used to transfer control. このグループには、breakcontinuegotothrowreturn、および yield ステートメントが含まれます。In this group are the break, continue, goto, throw, return, and yield statements.

try...catch ステートメントはブロックの実行中に発生した例外をキャッチするために使用し、try...finally ステートメントは例外が発生したかどうかにかかわらず常に実行される終了処理コードを指定するために使用します。The try...catch statement is used to catch exceptions that occur during execution of a block, and the try...finally statement is used to specify finalization code that is always executed, whether an exception occurred or not.

checkedおよびステートメントは、 unchecked 整数型の算術演算および変換のオーバーフローチェックコンテキストを制御するために使用されます。The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

lock ステートメントは、指定のオブジェクトに対する相互排他ロックを取得し、ステートメントを実行してからロックを解放するために使用します。The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

using ステートメントは、リソースを取得し、ステートメントを実行してからそのリソースを破棄するために使用します。The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

各種類のステートメントの例を次に示します。Below are examples of each kind of statement

ローカル変数の宣言Local variable declarations

static void Main() {
   int a;
   int b = 2, c = 3;
   a = 1;
   Console.WriteLine(a + b + c);
}

ローカル定数宣言Local constant declaration

static void Main() {
    const float pi = 3.1415927f;
    const int r = 25;
    Console.WriteLine(pi * r * r);
}

式ステートメントExpression statement

static void Main() {
    int i;
    i = 123;                // Expression statement
    Console.WriteLine(i);   // Expression statement
    i++;                    // Expression statement
    Console.WriteLine(i);   // Expression statement
}

if ステートメントif statement

static void Main(string[] args) {
    if (args.Length == 0) {
        Console.WriteLine("No arguments");
    }
    else {
        Console.WriteLine("One or more arguments");
    }
}

switch ステートメントswitch statement

static void Main(string[] args) {
    int n = args.Length;
    switch (n) {
        case 0:
            Console.WriteLine("No arguments");
            break;
        case 1:
            Console.WriteLine("One argument");
            break;
        default:
            Console.WriteLine("{0} arguments", n);
            break;
    }
}

while ステートメントwhile statement

static void Main(string[] args) {
    int i = 0;
    while (i < args.Length) {
        Console.WriteLine(args[i]);
        i++;
    }
}

do ステートメントdo statement

static void Main() {
    string s;
    do {
        s = Console.ReadLine();
        if (s != null) Console.WriteLine(s);
    } while (s != null);
}

for ステートメントfor statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        Console.WriteLine(args[i]);
    }
}

foreach ステートメントforeach statement

static void Main(string[] args) {
    foreach (string s in args) {
        Console.WriteLine(s);
    }
}

break ステートメントbreak statement

static void Main() {
    while (true) {
        string s = Console.ReadLine();
        if (s == null) break;
        Console.WriteLine(s);
    }
}

continue ステートメントcontinue statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        if (args[i].StartsWith("/")) continue;
        Console.WriteLine(args[i]);
    }
}

goto ステートメントgoto statement

static void Main(string[] args) {
    int i = 0;
    goto check;
    loop:
    Console.WriteLine(args[i++]);
    check:
    if (i < args.Length) goto loop;
}

return ステートメントreturn statement

static int Add(int a, int b) {
    return a + b;
}

static void Main() {
    Console.WriteLine(Add(1, 2));
    return;
}

yield ステートメントyield statement

static IEnumerable<int> Range(int from, int to) {
    for (int i = from; i < to; i++) {
        yield return i;
    }
    yield break;
}

static void Main() {
    foreach (int x in Range(-10,10)) {
        Console.WriteLine(x);
    }
}

throw``tryステートメントとステートメントthrow and try statements

static double Divide(double x, double y) {
    if (y == 0) throw new DivideByZeroException();
    return x / y;
}

static void Main(string[] args) {
    try {
        if (args.Length != 2) {
            throw new Exception("Two numbers required");
        }
        double x = double.Parse(args[0]);
        double y = double.Parse(args[1]);
        Console.WriteLine(Divide(x, y));
    }
    catch (Exception e) {
        Console.WriteLine(e.Message);
    }
    finally {
        Console.WriteLine("Good bye!");
    }
}

checked``uncheckedステートメントとステートメントchecked and unchecked statements

static void Main() {
    int i = int.MaxValue;
    checked {
        Console.WriteLine(i + 1);        // Exception
    }
    unchecked {
        Console.WriteLine(i + 1);        // Overflow
    }
}

lock ステートメントlock statement

class Account
{
    decimal balance;
    public void Withdraw(decimal amount) {
        lock (this) {
            if (amount > balance) {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

using ステートメントusing statement

static void Main() {
    using (TextWriter w = File.CreateText("test.txt")) {
        w.WriteLine("Line one");
        w.WriteLine("Line two");
        w.WriteLine("Line three");
    }
}

クラスとオブジェクトClasses and objects

*クラス _ は、C# の最も基本的な型です。*Classes _ are the most fundamental of C#'s types. クラスは、状態 (フィールド) とアクション (メソッドおよびその他の関数メンバー) を 1 つの単位としてまとめたデータ構造です。A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. クラスは、動的に作成されたクラスの *インスタンス* ( *オブジェクト* とも呼ばれます) の定義を提供します。A class provides a definition for dynamically created instances of the class, also known as objects. クラスは、*派生クラス* が _ 基底クラス * を拡張および特殊化できる機構である *継承**ポリモーフィズム* をサポートしています。Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize _*base classes**.

新しいクラスはクラス宣言を使用して作成されます。New classes are created using class declarations. クラス宣言は、クラスの属性と修飾子、クラスの名前、基底クラス (指定されている場合)、およびクラスによって実装されるインターフェイスを指定するヘッダーで開始します。A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. ヘッダーの後にはクラス本体が続きます。これは、区切り記号 {} の間に記述するメンバー宣言のリストで構成されます。The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Point という名前の単純なクラスの宣言を次に示します。The following is a declaration of a simple class named Point:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

クラスのインスタンスは new 演算子を使用して作成されます。この演算子は新しいインスタンスのメモリを割り当て、コンストラクターを呼び出してインスタンスを初期化し、インスタンスへの参照を返します。Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. 次のステートメントは、2 つの Point オブジェクトを作成し、2 つの変数に、それらのオブジェクトへの参照を格納します。The following statements create two Point objects and store references to those objects in two variables:

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

オブジェクトによって占有されているメモリは、オブジェクトが使用されなくなったときに自動的に解放されます。The memory occupied by an object is automatically reclaimed when the object is no longer in use. C# では、オブジェクトの割り当てを明示的に解除する必要がなく、また解除することもできません。It is neither necessary nor possible to explicitly deallocate objects in C#.

メンバーMembers

クラスのメンバーは、*静的メンバー _ または _ インスタンスメンバー * のいずれかです。The members of a class are either static members _ or _instance members**. 静的メンバーはクラスに属しており、インスタンス メンバーはオブジェクト (クラスのインスタンス) に属しています。Static members belong to classes, and instance members belong to objects (instances of classes).

次の表は、クラスに含めることができるメンバーの種類の概要を示しています。The following table provides an overview of the kinds of members a class can contain.

メンバーMember 説明Description
定数Constants クラスに関連付けられている定数値Constant values associated with the class
フィールドFields クラスの変数Variables of the class
メソッドMethods クラスによって実行可能な計算とアクションComputations and actions that can be performed by the class
PropertiesProperties クラスの名前付きプロパティの読み取りと書き込みに関連付けられているアクションActions associated with reading and writing named properties of the class
インデクサーIndexers 配列など、クラスのインスタンスのインデックス作成に関連付けられているアクションActions associated with indexing instances of the class like an array
イベントEvents クラスによって生成可能な通知Notifications that can be generated by the class
オペレーターOperators クラスによってサポートされている変換と式の演算子Conversions and expression operators supported by the class
コンストラクターConstructors クラスのインスタンスまたはクラス自体を初期化するために必要なアクションActions required to initialize instances of the class or the class itself
デストラクターDestructors クラスのインスタンスが完全に破棄される前に実行するアクションActions to perform before instances of the class are permanently discarded
種類Types クラスで宣言される、入れ子にされた型Nested types declared by the class

ユーザー補助Accessibility

クラスの各メンバーにはアクセシビリティが関連付けられています。アクセシビリティは、メンバーへのアクセスが可能なプログラムのテキストの範囲を制御します。Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. アクセシビリティには 5 つの有効な形式があります。There are five possible forms of accessibility. これらの概要を次の表に示します。These are summarized in the following table.

アクセシビリティAccessibility 意味Meaning
public アクセスは制限されません。Access not limited
protected アクセスは、このクラスまたはこのクラスから派生したクラスに制限されます。Access limited to this class or classes derived from this class
internal アクセスはこのプログラムに制限されます。Access limited to this program
protected internal アクセスは、このプログラムまたはこのクラスから派生したクラスに制限されます。Access limited to this program or classes derived from this class
private アクセスはこのクラスに制限されます。Access limited to this class

型パラメーターType parameters

クラス定義では、クラス名の後に型パラメーター名のリストを山かっこで囲むことで、型パラメーターのセットを指定できます。A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. これで、クラスのメンバーを定義するクラス宣言の本体で型パラメーターを使用できます。The type parameters can then be used in the body of the class declarations to define the members of the class. 次の例では、Pair の型パラメーターは TFirstTSecond です。In the following example, the type parameters of Pair are TFirst and TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

型パラメーターを受け取るように宣言されているクラス型は、ジェネリッククラス型と呼ばれます。A class type that is declared to take type parameters is called a generic class type. 構造体、インターフェイス、およびデリゲートの型もジェネリックです。Struct, interface and delegate types can also be generic.

ジェネリック クラスを使用する場合は、それぞれの型パラメーターの型引数を指定する必要があります。When the generic class is used, type arguments must be provided for each of the type parameters:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

上記のように、指定された型引数を持つジェネリック型 Pair<int,string> は、構築された型と呼ばれます。A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

基底クラスBase classes

クラス宣言では、クラス名と型パラメーターの後にコロンと基底クラスの名前を入力することで、基底クラスを指定できます。A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. 基底クラスの指定の省略は、object 型からの派生と同じです。Omitting a base class specification is the same as deriving from type object. 次の例では、Point3D の基底クラスは Point であり、Point の基底クラスは object です。In the following example, the base class of Point3D is Point, and the base class of Point is object:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Point3D: Point
{
    public int z;

    public Point3D(int x, int y, int z): base(x, y) {
        this.z = z;
    }
}

クラスは、その基底クラスのメンバーを継承します。A class inherits the members of its base class. 継承とは、クラスに基底クラスのすべてのメンバーが暗黙的に格納されることを意味します。ただし、インスタンスコンストラクターと静的コンストラクター、および基底クラスのデストラクターは除きます。Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the destructors of the base class. 派生クラスは、継承するメンバーに新しいメンバーを追加できますが、継承されたメンバーの定義を削除することはできません。A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. 前述の例では、Point3D は、Point から x フィールドと y フィールドを継承します。各 Point3D インスタンスには、xyz の 3 つのフィールドが含まれています。In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

暗黙的な変換は、クラス型からその基底クラス型のいずれかに存在します。An implicit conversion exists from a class type to any of its base class types. そのため、クラス型の変数は、そのクラスのインスタンスまたは任意の派生クラスのインスタンスを参照できます。Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. たとえば、前述のクラス宣言では、Point 型の変数が Point または Point3D を参照できます。For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

フィールドFields

"フィールド" は、クラスまたはクラスのインスタンスに関連付けられている変数です。A field is a variable that is associated with a class or with an instance of a class.

修飾子を使用して宣言されたフィールドは、 static 静的フィールド を定義します。A field declared with the static modifier defines a static field. 静的フィールドは、格納場所を 1 つだけ識別します。A static field identifies exactly one storage location. クラスのインスタンスがいくつ作成されても、静的フィールドのコピーは 1 つだけです。No matter how many instances of a class are created, there is only ever one copy of a static field.

修飾子を指定せずに宣言されたフィールドは、 static インスタンスフィールド を定義します。A field declared without the static modifier defines an instance field. クラスの各インスタンスには、そのクラスのすべてのインスタンス フィールドの個別のコピーが含まれています。Every instance of a class contains a separate copy of all the instance fields of that class.

次の例では、Color クラスの各インスタンスに、インスタンス フィールド rgb の個別のコピーが含まれていますが、静的フィールド BlackWhiteRedGreenBlue のコピーは 1 つだけです。In the following example, each instance of the Color class has a separate copy of the r, g, and b instance fields, but there is only one copy of the Black, White, Red, Green, and Blue static fields:

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte r, g, b;

    public Color(byte r, byte g, byte b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

前述の例のように、readonly 修飾子を使用して "読み取り専用フィールド" を宣言できます。As shown in the previous example, read-only fields may be declared with a readonly modifier. フィールドへの割り当て readonly は、フィールドの宣言の一部として、または同じクラスのコンストラクター内でのみ行うことができます。Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

メソッドMethods

*メソッド _ は、オブジェクトまたはクラスによって実行できる計算またはアクションを実装するメンバーです。A *method _ is a member that implements a computation or action that can be performed by an object or class. *静的メソッド* には、クラスを使用してアクセスします。Static methods are accessed through the class. _ インスタンスメソッド* は、クラスのインスタンスを介してアクセスされます。_ Instance methods* are accessed through instances of the class.

メソッドには、メソッドに渡された値または変数参照を表す parameters _ のリスト (空の場合もあります) と、メソッドによって計算および返される値の型を指定する _ * 戻り値の * があります。Methods have a (possibly empty) list of parameters _, which represent values or variable references passed to the method, and a _return type**, which specifies the type of the value computed and returned by the method. メソッドの戻り値の型は、 void 値を返さない場合はです。A method's return type is void if it does not return a value.

型と同様に、メソッドには型パラメーターのセットを含めることができます。その場合、メソッドの呼び出し時に型引数を指定する必要があります。Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. 型引数は、型とは異なり、多くの場合メソッド呼び出しの引数から推論できます。型引数を明示的に指定する必要はありません。Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

メソッドの "シグネチャ" は、メソッドが宣言されているクラス内で一意である必要があります。The signature of a method must be unique in the class in which the method is declared. メソッドのシグネチャは、メソッドの名前、型パラメーターの数、およびメソッドのパラメーターの数、修飾子、型で構成されます。The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. メソッドのシグネチャに戻り値の型は含まれません。The signature of a method does not include the return type.

パラメーターParameters

パラメーターは、値または変数参照をメソッドに渡すために使用されます。Parameters are used to pass values or variable references to methods. メソッドのパラメーターは、メソッドの呼び出し時に指定する "引数" から実際の値を取得します。The parameters of a method get their actual values from the arguments that are specified when the method is invoked. 値パラメーター、参照パラメーター、出力パラメーター、およびパラメーター配列の 4 種類のパラメーターがあります。There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

"値パラメーター" は入力パラメーターの引き渡しに使用します。A value parameter is used for input parameter passing. 値パラメーターは、パラメーターに渡された引数からその初期値を取得するローカル変数に相当します。A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. 値パラメーターに対する変更は、パラメーターに渡された引数には影響しません。Modifications to a value parameter do not affect the argument that was passed for the parameter.

値パラメーターは省略可能であり、既定値を指定すると、対応する引数を省略できます。Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

"参照パラメーター" は入力パラメーターと出力パラメーターの引き渡しに使用します。A reference parameter is used for both input and output parameter passing. 参照パラメーターに渡す引数は変数である必要があり、メソッドの実行中に、参照パラメーターは引数の変数と同じ格納場所を表します。The argument passed for a reference parameter must be a variable, and during execution of the method, the reference parameter represents the same storage location as the argument variable. 参照パラメーターは、ref 修飾子で宣言されます。A reference parameter is declared with the ref modifier. ref パラメーターの使用例を次に示します。The following example shows the use of ref parameters.

using System;

class Test
{
    static void Swap(ref int x, ref int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    static void Main() {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine("{0} {1}", i, j);            // Outputs "2 1"
    }
}

"出力パラメーター" は出力パラメーターの引き渡しに使用します。An output parameter is used for output parameter passing. 呼び出し元が提供する引数の初期値が重要でないことを除き、出力パラメーターは参照パラメーターと同様です。An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. 出力パラメーターは、out 修飾子で宣言されます。An output parameter is declared with the out modifier. out パラメーターの使用例を次に示します。The following example shows the use of out parameters.

using System;

class Test
{
    static void Divide(int x, int y, out int result, out int remainder) {
        result = x / y;
        remainder = x % y;
    }

    static void Main() {
        int res, rem;
        Divide(10, 3, out res, out rem);
        Console.WriteLine("{0} {1}", res, rem);    // Outputs "3 1"
    }
}

"パラメーター配列" は、引数の変数の数をメソッドに渡せるようにします。A parameter array permits a variable number of arguments to be passed to a method. パラメーター配列は、params 修飾子で宣言されます。A parameter array is declared with the params modifier. パラメーター配列として使用できるのは、メソッドの最後のパラメーターのみです。パラメーター配列の型は、1 次元配列の型である必要があります。Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. System.Console クラスの Write および WriteLine メソッドは、パラメーター配列の使用方法の好例です。The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. これらのメソッドは次のように宣言されます。They are declared as follows.

public class Console
{
    public static void Write(string fmt, params object[] args) {...}
    public static void WriteLine(string fmt, params object[] args) {...}
    ...
}

パラメーター配列を使用するメソッド内では、パラメーター配列は、配列型の通常のパラメーターとまったく同じように動作します。Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. ただし、パラメーター配列を使用するメソッドの呼び出しでは、パラメーター配列の型の 1 つの引数またはパラメーター配列の要素型の任意の数の引数を渡すことができます。However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. 後者の場合、配列インスタンスが自動的に作成され、指定した引数を使用して初期化されます。In the latter case, an array instance is automatically created and initialized with the given arguments. 次のような例があるとします。This example

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

これは、次の記述と同じです。is equivalent to writing the following.

string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

メソッドの本体とローカル変数Method body and local variables

メソッドの本体は、メソッドが呼び出されたときに実行するステートメントを指定します。A method's body specifies the statements to execute when the method is invoked.

メソッドの本体は、メソッドの呼び出しに固有の変数を宣言できます。A method body can declare variables that are specific to the invocation of the method. このような変数は "ローカル変数" と呼ばれます。Such variables are called local variables. ローカル変数宣言は、型名、変数名、および (場合によっては) 初期値を指定します。A local variable declaration specifies a type name, a variable name, and possibly an initial value. 次の例では、初期値 0 を使用してローカル変数 i を宣言し、初期値を使用せずにローカル変数 j を宣言します。The following example declares a local variable i with an initial value of zero and a local variable j with no initial value.

using System;

class Squares
{
    static void Main() {
        int i = 0;
        int j;
        while (i < 10) {
            j = i * i;
            Console.WriteLine("{0} x {0} = {1}", i, j);
            i = i + 1;
        }
    }
}

C# では、ローカル変数の値を取得する前に、ローカル変数を "明示的に割り当てる" 必要があります。C# requires a local variable to be definitely assigned before its value can be obtained. たとえば、前述の i の宣言に初期値が含まれていなかった場合、コンパイラは以降の i の使用に対するエラーを報告します。これは、プログラム内のそれらのポイントで i が明示的に割り当てられていないためです。For example, if the declaration of the previous i did not include an initial value, the compiler would report an error for the subsequent usages of i because i would not be definitely assigned at those points in the program.

メソッドでは、return ステートメントを使用して、呼び出し元に制御を戻すことができます。A method can use return statements to return control to its caller. void を返すメソッドの場合、return ステートメントは式を指定できません。In a method returning void, return statements cannot specify an expression. 以外のステートメントを返すメソッドでは voidreturn ステートメントに戻り値を計算する式を含める必要があります。In a method returning non-void, return statements must include an expression that computes the return value.

静的メソッドとインスタンス メソッドStatic and instance methods

static 修飾子で宣言されているメソッドは "静的メソッド" です。A method declared with a static modifier is a static method. 静的メソッドは、特定のインスタンスでは動作せず、静的メンバーにのみ直接アクセスできます。A static method does not operate on a specific instance and can only directly access static members.

static 修飾子なしで宣言されているメソッドは "インスタンス メソッド" です。A method declared without a static modifier is an instance method. インスタンス メソッドは、特定のインスタンスで動作し、静的メンバーとインスタンス メンバーの両方にアクセスできます。An instance method operates on a specific instance and can access both static and instance members. インスタンス メソッドが呼び出されたインスタンスには、this として明示的にアクセスできます。The instance on which an instance method was invoked can be explicitly accessed as this. 静的メソッドで this を参照するとエラーになります。It is an error to refer to this in a static method.

次の Entity クラスには、静的メンバーとインスタンス メンバーの両方があります。The following Entity class has both static and instance members.

class Entity
{
    static int nextSerialNo;
    int serialNo;

    public Entity() {
        serialNo = nextSerialNo++;
    }

    public int GetSerialNo() {
        return serialNo;
    }

    public static int GetNextSerialNo() {
        return nextSerialNo;
    }

    public static void SetNextSerialNo(int value) {
        nextSerialNo = value;
    }
}

Entity インスタンスには、シリアル番号 (およびここに表示されていないその他の情報) が含まれています。Each Entity instance contains a serial number (and presumably some other information that is not shown here). Entity コンストラクターは (インスタンス メソッドと同様に)、次に使用可能なシリアル番号を持つ新しいインスタンスを初期化します。The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. コンストラクターはインスタンス メンバーであるため、serialNo インスタンス フィールドと nextSerialNo 静的フィールドの両方にアクセスできます。Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

静的メソッドである GetNextSerialNoSetNextSerialNonextSerialNo 静的フィールドにアクセスできますが、serialNo インスタンス フィールドに直接アクセスするとエラーになります。The GetNextSerialNo and SetNextSerialNo static methods can access the nextSerialNo static field, but it would be an error for them to directly access the serialNo instance field.

Entity クラスの使用例を次に示します。The following example shows the use of the Entity class.

using System;

class Test
{
    static void Main() {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());           // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());           // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());   // Outputs "1002"
    }
}

静的メソッドである SetNextSerialNoGetNextSerialNo はクラスで呼び出されますが、GetSerialNo インスタンス メソッドはクラスのインスタンスで呼び出されます。Note that the SetNextSerialNo and GetNextSerialNo static methods are invoked on the class whereas the GetSerialNo instance method is invoked on instances of the class.

仮想メソッド、オーバーライド メソッド、および抽象メソッドVirtual, override, and abstract methods

インスタンスメソッドの宣言に修飾子が含まれている場合 virtual 、メソッドは *仮想メソッド _ と呼ばれます。When an instance method declaration includes a virtual modifier, the method is said to be a *virtual method . virtual修飾子が存在しない場合、メソッドは、 非仮想メソッド * と呼ばれます。When no virtual modifier is present, the method is said to be a _*non-virtual method**.

仮想メソッドが呼び出されると、呼び出し元のインスタンスの *実行時の型 _ によって、呼び出す実際のメソッドの実装が決まります。When a virtual method is invoked, the *run-time type _ of the instance for which that invocation takes place determines the actual method implementation to invoke. 非仮想メソッドの呼び出しでは、インスタンスの _ コンパイル時の型* が決定要因になります。In a nonvirtual method invocation, the _ compile-time type* of the instance is the determining factor.

仮想メソッドは派生クラスで "オーバーライド" できます。A virtual method can be overridden in a derived class. インスタンスメソッドの宣言に修飾子が含まれている場合 override 、メソッドは、同じシグネチャを持つ継承された仮想メソッドをオーバーライドします。When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. 仮想メソッドの宣言には新しいメソッドが導入されていますが、オーバーライド メソッドの宣言では、そのメソッドの新しい実装を提供することで既存の継承された仮想メソッドを特殊化します。Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.

抽象 メソッドは、実装のない仮想メソッドです。An abstract method is a virtual method with no implementation. 抽象メソッドは修飾子を使用して宣言され、 abstract 宣言されているクラスでのみ許可され abstract ます。An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. 抽象メソッドは、すべての非抽象派生クラスでオーバーライドする必要があります。An abstract method must be overridden in every non-abstract derived class.

次の例では、式ツリー ノードを表す抽象クラス Expression、および定数、変数参照、算術演算の式ツリー ノードを実装する 3 つの派生クラス ConstantVariableReferenceOperation を宣言します The following example declares an abstract class, Expression, which represents an expression tree node, and three derived classes, Constant, VariableReference, and Operation, which implement expression tree nodes for constants, variable references, and arithmetic operations. (これはと似ていますが、 式ツリー型で導入された式ツリー型と混同することはありません)。(This is similar to, but not to be confused with the expression tree types introduced in Expression tree types).

using System;
using System.Collections;

public abstract class Expression
{
    public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression
{
    double value;

    public Constant(double value) {
        this.value = value;
    }

    public override double Evaluate(Hashtable vars) {
        return value;
    }
}

public class VariableReference: Expression
{
    string name;

    public VariableReference(string name) {
        this.name = name;
    }

    public override double Evaluate(Hashtable vars) {
        object value = vars[name];
        if (value == null) {
            throw new Exception("Unknown variable: " + name);
        }
        return Convert.ToDouble(value);
    }
}

public class Operation: Expression
{
    Expression left;
    char op;
    Expression right;

    public Operation(Expression left, char op, Expression right) {
        this.left = left;
        this.op = op;
        this.right = right;
    }

    public override double Evaluate(Hashtable vars) {
        double x = left.Evaluate(vars);
        double y = right.Evaluate(vars);
        switch (op) {
            case '+': return x + y;
            case '-': return x - y;
            case '*': return x * y;
            case '/': return x / y;
        }
        throw new Exception("Unknown operator");
    }
}

前述の 4 つのクラスは、算術式をモデル化するために使用できます。The previous four classes can be used to model arithmetic expressions. たとえば、これらのクラスのインスタンスを使用して、式 x + 3 を次のように表すことができます。For example, using instances of these classes, the expression x + 3 can be represented as follows.

Expression e = new Operation(
    new VariableReference("x"),
    '+',
    new Constant(3));

Expression インスタンスの Evaluate メソッドが呼び出され、指定された式を評価して double 値を生成します。The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. メソッドは、(エントリの Hashtable キーとしての) 変数名と値 (エントリの値) を格納する引数としてを受け取ります。The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). Evaluateメソッドは仮想抽象メソッドです。つまり、抽象でない派生クラスは、実際の実装を提供するためにオーバーライドする必要があります。The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

EvaluateConstant の実装は、格納された定数を単に返します。A Constant's implementation of Evaluate simply returns the stored constant. VariableReferenceの実装は、ハッシュテーブル内の変数名を検索し、結果の値を返します。A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Operation の実装は、(Evaluate メソッドを再帰的に呼び出すことによって) まず左と右のオペランドを評価し、指定された算術演算を実行します。An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

次のプログラムでは、Expression クラスを使用して、式 x * (y + 2) の異なる値の xy を評価します。The following program uses the Expression classes to evaluate the expression x * (y + 2) for different values of x and y.

using System;
using System.Collections;

class Test
{
    static void Main() {
        Expression e = new Operation(
            new VariableReference("x"),
            '*',
            new Operation(
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        Hashtable vars = new Hashtable();
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "16.5"
    }
}

メソッドのオーバーロードMethod overloading

メソッド *オーバーロード _ では、一意のシグネチャを持つ限り、同じクラスの複数のメソッドが同じ名前を持つことができます。Method *overloading _ permits multiple methods in the same class to have the same name as long as they have unique signatures. オーバーロードされたメソッドの呼び出しをコンパイルするときに、コンパイラは _ オーバーロード解決* を使用して、呼び出す特定のメソッドを決定します。When compiling an invocation of an overloaded method, the compiler uses _ overload resolution* to determine the specific method to invoke. オーバーロードの解決では、引数に最も一致する 1 つのメソッドが特定されます。最も一致するメソッドが見つからない場合は、エラーが報告されます。Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. 次の例は、オーバーロードの解決が有効な場合を示しています。The following example shows overload resolution in effect. Main メソッド内の各呼び出しのコメントは、実際に呼び出されるメソッドを示しています。The comment for each invocation in the Main method shows which method is actually invoked.

class Test
{
    static void F() {
        Console.WriteLine("F()");
    }

    static void F(object x) {
        Console.WriteLine("F(object)");
    }

    static void F(int x) {
        Console.WriteLine("F(int)");
    }

    static void F(double x) {
        Console.WriteLine("F(double)");
    }

    static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");
    }

    static void F(double x, double y) {
        Console.WriteLine("F(double, double)");
    }

    static void Main() {
        F();                 // Invokes F()
        F(1);                // Invokes F(int)
        F(1.0);              // Invokes F(double)
        F("abc");            // Invokes F(object)
        F((double)1);        // Invokes F(double)
        F((object)1);        // Invokes F(object)
        F<int>(1);           // Invokes F<T>(T)
        F(1, 1);             // Invokes F(double, double)
    }
}

この例に示すように、パラメーターの厳密な型に引数を明示的にキャストするか、または型引数を明示的に指定することにより、特定のメソッドを常に選択できます。As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.

その他の関数メンバーOther function members

実行可能コードが含まれるメンバーは、クラスの "関数メンバー" と総称されます。Members that contain executable code are collectively known as the function members of a class. 前のセクションでは、関数メンバーの主な種類であるメソッドについて説明しました。The preceding section describes methods, which are the primary kind of function members. このセクションでは、C# でサポートされている他の種類の関数メンバー (コンストラクター、プロパティ、インデクサー、イベント、演算子、およびデストラクター) について説明します。This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

次のコードは List<T> 、オブジェクトの growable リストを実装するという名前のジェネリッククラスを示しています。The following code shows a generic class called List<T>, which implements a growable list of objects. このクラスには、最も一般的な種類の関数メンバーの例がいくつか含まれています。The class contains several examples of the most common kinds of function members.

public class List<T> {
    // Constant...
    const int defaultCapacity = 4;

    // Fields...
    T[] items;
    int count;

    // Constructors...
    public List(int capacity = defaultCapacity) {
        items = new T[capacity];
    }

    // Properties...
    public int Count {
        get { return count; }
    }
    public int Capacity {
        get {
            return items.Length;
        }
        set {
            if (value < count) value = count;
            if (value != items.Length) {
                T[] newItems = new T[value];
                Array.Copy(items, 0, newItems, 0, count);
                items = newItems;
            }
        }
    }

    // Indexer...
    public T this[int index] {
        get {
            return items[index];
        }
        set {
            items[index] = value;
            OnChanged();
        }
    }

    // Methods...
    public void Add(T item) {
        if (count == Capacity) Capacity = count * 2;
        items[count] = item;
        count++;
        OnChanged();
    }
    protected virtual void OnChanged() {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public override bool Equals(object other) {
        return Equals(this, other as List<T>);
    }
    static bool Equals(List<T> a, List<T> b) {
        if (a == null) return b == null;
        if (b == null || a.count != b.count) return false;
        for (int i = 0; i < a.count; i++) {
            if (!object.Equals(a.items[i], b.items[i])) {
                return false;
            }
        }
        return true;
    }

    // Event...
    public event EventHandler Changed;

    // Operators...
    public static bool operator ==(List<T> a, List<T> b) {
        return Equals(a, b);
    }
    public static bool operator !=(List<T> a, List<T> b) {
        return !Equals(a, b);
    }
}

コンストラクターConstructors

C# は、インスタンス コンストラクターと静的コンストラクターの両方をサポートします。C# supports both instance and static constructors. *インスタンスコンストラクター _ は、クラスのインスタンスを初期化するために必要なアクションを実装するメンバーです。An *instance constructor _ is a member that implements the actions required to initialize an instance of a class. _ 静的コンストラクター* は、最初に読み込まれたときにクラス自体を初期化するために必要なアクションを実装するメンバーです。A _ static constructor* is a member that implements the actions required to initialize a class itself when it is first loaded.

コンストラクターは、戻り値の型がなく、含んでいるクラスと同じ名前を持つメソッドのように宣言されます。A constructor is declared like a method with no return type and the same name as the containing class. コンストラクターの宣言に static 修飾子が含まれている場合は、静的コンストラクターが宣言されます。If a constructor declaration includes a static modifier, it declares a static constructor. それ以外の場合は、インスタンス コンストラクターが宣言されます。Otherwise, it declares an instance constructor.

インスタンスコンストラクターはオーバーロードできます。Instance constructors can be overloaded. たとえば、List<T> クラスは、2 つの (1 つはパラメーターなし、もう 1 つは int パラメーターを受け取る) インスタンス コンストラクターを宣言します。For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. インスタンス コンストラクターは、new 演算子を使用して呼び出されます。Instance constructors are invoked using the new operator. 次のステートメントは、 List<string> クラスの各コンストラクターを使用して2つのインスタンスを割り当て List ます。The following statements allocate two List<string> instances using each of the constructors of the List class.

List<string> list1 = new List<string>();
List<string> list2 = new List<string>(10);

他のメンバーとは異なり、インスタンス コンストラクターは継承されず、クラスには、そのクラスで実際に宣言された以外のインスタンス コンストラクターがありません。Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. クラスのインスタンス コンストラクターが指定されていない場合は、パラメーターなしの空のコンストラクターが自動的に指定されます。If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

プロパティProperties

*プロパティ _ は、フィールドの自然な拡張です。*Properties _ are a natural extension of fields. フィールドとプロパティはどちらも型が関連付けられている名前付きのメンバーであり、それらにアクセスするための構文は同じです。Both are named members with associated types, and the syntax for accessing fields and properties is the same. ただし、フィールドとは異なり、プロパティは格納場所を表しません。However, unlike fields, properties do not denote storage locations. プロパティには、その値が読み取られたとき、または書き込まれたときに実行されるステートメントを指定する _ アクセサー* があります。Instead, properties have _ accessors* that specify the statements to be executed when their values are read or written.

プロパティはフィールドのように宣言されますが、宣言は、 get set { セミコロンで終わるのではなく、区切り記号との間に記述されたアクセサーまたはアクセサーで終了する点が異なり } ます。A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. アクセサーとアクセサーの両方を持つプロパティ get set は、読み取り/書き込みプロパティ _、アクセサーだけを持つプロパティは読み取り専用 get _プロパティ*、アクセサーだけを持つプロパティは、 set _ *書き込み専用のプロパティ* * ですが、プロパティは * * です。A property that has both a get accessor and a set accessor is a read-write property _, a property that has only a get accessor is a _read-only property*, and a property that has only a set accessor is a _*write-only property**.

アクセサーは、 get プロパティの型の戻り値を持つパラメーターなしのメソッドに対応します。A get accessor corresponds to a parameterless method with a return value of the property type. 代入の対象として、プロパティが式で参照されている場合は、プロパティの get アクセサーが呼び出され、プロパティの値が計算されます。Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.

アクセサーは、 set という名前の1つのパラメーターを持ち、戻り値の型を持たないメソッドに対応し value ます。A set accessor corresponds to a method with a single parameter named value and no return type. プロパティが代入のターゲットとして、またはまたはのオペランドとして参照されている場合、 ++ -- set アクセサーは新しい値を提供する引数を使用して呼び出されます。When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.

List<T> クラスは 2 つのプロパティ (CountCapacity) を宣言します。これらは、それぞれ読み取り専用プロパティと読み取り/書き込みプロパティです。The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. これらのプロパティの使用例を次に示します。The following is an example of use of these properties.

List<string> names = new List<string>();
names.Capacity = 100;            // Invokes set accessor
int i = names.Count;             // Invokes get accessor
int j = names.Capacity;          // Invokes get accessor

フィールドおよびメソッドと同様に、C# はインスタンス プロパティと静的プロパティの両方をサポートします。Similar to fields and methods, C# supports both instance properties and static properties. 静的プロパティは修飾子を使用して宣言され、 static インスタンスプロパティは使用されずに宣言されます。Static properties are declared with the static modifier, and instance properties are declared without it.

プロパティのアクセサーは仮想にすることができます。The accessor(s) of a property can be virtual. プロパティの宣言に virtualabstract、または override の各修飾子が含まれている場合、その宣言はプロパティのアクセサーに適用されます。When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

インデクサーIndexers

"インデクサー" は、配列と同じ方法でオブジェクトのインデックスを作成できるようにするメンバーです。An indexer is a member that enables objects to be indexed in the same way as an array. インデクサーはプロパティのように宣言されますが、メンバーの名前が、this の後に区切り記号 [] でパラメーター リストを囲んだものになる点が異なります。An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ]. パラメーターは、インデクサーのアクセサーで使用できます。The parameters are available in the accessor(s) of the indexer. プロパティと同様に、読み取り/書き込み、読み取り専用、および書き込み専用のインデクサーを使用できます。また、インデクサーのアクセサーを仮想にすることができます。Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

List クラスは、int パラメーターを受け取る 1 つの読み取り/書き込みインデクサーを宣言します。The List class declares a single read-write indexer that takes an int parameter. インデクサーを使用すると、int 値を持つ List インスタンスのインデックスを作成できます。The indexer makes it possible to index List instances with int values. 次に例を示します。For example

List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
    string s = names[i];
    names[i] = s.ToUpper();
}

インデクサーはオーバーロードできます。つまり、パラメーターの数または型が異なる限り、クラスは複数のインデクサーを宣言できます。Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

eventsEvents

"イベント" は、クラスまたはオブジェクトで通知を提供できるようにするメンバーです。An event is a member that enables a class or object to provide notifications. イベントはフィールドのように宣言されますが、event キーワードが宣言に含まれており、型がデリゲート型でなければならない点が異なります。An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

イベント メンバーを宣言するクラス内では、イベントはデリゲート型のフィールドと同じように動作します (イベントが抽象イベントでなく、アクセサーを宣言しない場合)。Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). フィールドは、イベントに追加されたイベント ハンドラーを表すデリゲートへの参照を格納します。The field stores a reference to a delegate that represents the event handlers that have been added to the event. イベントハンドルが存在しない場合、フィールドは null です。If no event handles are present, the field is null.

List<T> クラスは、Changed という 1 つのイベント メンバーを宣言します。このメンバーは新しい項目がリストに追加されたことを示します。The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. イベントは、 Changed 仮想メソッドによって発生し OnChanged ます。このメソッドは、イベントが null (ハンドラーが存在しないことを意味する) であるかどうかを最初に確認します。The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). イベントを発生させるという概念は、イベントによって表されるデリゲートの呼び出しとまったく同じです。したがって、イベントを発生させるための特殊な言語コンストラクトはありません。The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

クライアントは、"イベント ハンドラー" を使用してイベントに対応します。Clients react to events through event handlers. イベント ハンドラーは、+= 演算子を使用してアタッチされ、-= 演算子を使用して削除されます。Event handlers are attached using the += operator and removed using the -= operator. 次の例では、List<string>Changed イベントにイベント ハンドラーをアタッチします。The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
    static int changeCount;

    static void ListChanged(object sender, EventArgs e) {
        changeCount++;
    }

    static void Main() {
        List<string> names = new List<string>();
        names.Changed += new EventHandler(ListChanged);
        names.Add("Liz");
        names.Add("Martha");
        names.Add("Beth");
        Console.WriteLine(changeCount);        // Outputs "3"
    }
}

イベントの基になる記憶域の制御が求められる高度なシナリオでは、イベントの宣言で add アクセサーと remove アクセサーを明示的に指定できます。これらは、プロパティの set アクセサーにある程度似ています。For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

オペレーターOperators

"演算子" は、クラスのインスタンスに特定の式の演算子を適用する意味を定義するメンバーです。An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. 単項演算子、2 項演算子、および変換演算子の 3 種類を定義できます。Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. すべての演算子は public および static として宣言する必要があります。All operators must be declared as public and static.

List<T> クラスは 2 つの演算子 (operator==operator!=) を宣言し、List インスタンスにこれらの演算子を適用する式に新しい意味を持たせます。The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. 具体的には、Equals メソッドを使用して含まれている各オブジェクトを比較する際に、演算子が 2 つの List<T> インスタンスの等価性を定義します。Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. 次の例では、== 演算子を使用して 2 つの List<int> インスタンスを比較します。The following example uses the == operator to compare two List<int> instances.

using System;

class Test
{
    static void Main() {
        List<int> a = new List<int>();
        a.Add(1);
        a.Add(2);
        List<int> b = new List<int>();
        b.Add(1);
        b.Add(2);
        Console.WriteLine(a == b);        // Outputs "True"
        b.Add(3);
        Console.WriteLine(a == b);        // Outputs "False"
    }
}

最初の Console.WriteLineTrue を出力します。これは、2 つのリストに、同じ値を持つ同じ数のオブジェクトが同じ順序で含まれているためです。The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. List<T>operator== が定義されていない場合は、ab が異なる List<int> インスタンスを参照するため、最初の Console.WriteLineFalse を出力します。Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

デストラクターDestructors

デストラクター は、クラスのインスタンスを消滅させるために必要なアクションを実装するメンバーです。A destructor is a member that implements the actions required to destruct an instance of a class. デストラクターには、パラメーターを指定できません。また、アクセシビリティ修飾子は使用できず、明示的に呼び出すこともできません。Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. インスタンスのデストラクターは、ガベージコレクション中に自動的に呼び出されます。The destructor for an instance is invoked automatically during garbage collection.

ガベージコレクターでは、オブジェクトを収集してデストラクターを実行するタイミングを、ワイド緯度で決定できます。The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. 具体的には、デストラクター呼び出しのタイミングは決定的ではなく、デストラクターは任意のスレッドで実行できます。Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. これらの理由により、他のソリューションが実現できない場合にのみ、クラスはデストラクターを実装する必要があります。For these and other reasons, classes should implement destructors only when no other solutions are feasible.

using ステートメントは、オブジェクトを破棄するためのより適切な方法を提供します。The using statement provides a better approach to object destruction.

構造体Structs

構造体 は、クラスと同様に、データ メンバーおよび関数メンバーを含むことができるデータ構造ですが、値型でありヒープ割り当てを必要としない点でクラスと異なります。Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. 構造体型の変数は、構造体のデータを直接格納しますが、クラス型の変数は、動的に割り当てられたオブジェクトへの参照を格納します。A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. 構造体型はユーザー指定の継承をサポートせず、すべての構造体型は暗黙的に object 型を継承します。Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

構造体は、値セマンティクスを持つ小規模なデータ構造に特に便利です。Structs are particularly useful for small data structures that have value semantics. 構造体の主な例としては、複素数、座標系のポイント、ディクショナリのキーと値のペアなどがあります。Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. 小規模なデータ構造には、クラスよりむしろ構造体を使用するほうが、アプリケーションが実行するメモリ割り当ての数を大幅に減らすことができます。The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. たとえば、次のプログラムでは、100 個のポイントの配列を作成し初期化します。For example, the following program creates and initializes an array of 100 points. Point をクラスとして実装すると、101 個の別々のオブジェクトがインスタンス化されます。配列に1 個、残りは 100 個の要素に 1 個ずつです。With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Test
{
    static void Main() {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
    }
}

別の方法と Point して、構造体を作成することもできます。An alternative is to make Point a struct.

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

ここでは 1 つのオブジェクトのみがインスタンス化されます。すなわち、配列に 1 個です。そして、Point インスタンスがその配列内にインラインで格納されます。Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

構造体コンストラクターは new 演算子を使って呼び出されますが、メモリが割り当てられていることを意味するものではありません。Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. オブジェクトを動的に割り当てそこへの参照を返す代わりに、構造体コンストラクターは単に構造体の値自体 (通常、スタック上の一時的な場所) を返し、この値は必要に応じてコピーされます。Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

クラスを使用すると、2 つの変数が同じオブジェクトを参照できるため、1 つの変数に対する操作によって、もう一方の変数によって参照されるオブジェクトに影響を与えることができます。With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. 構造体を使用すると、各々の変数がデータのコピーを各々で持ち、1 つに対する操作がもう一方に影響を与えることはできません。With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. たとえば、次のコードフラグメントによって生成される出力は、がクラスであるか構造体であるかによって異なり Point ます。For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

がクラスである場合 Point 、とは 20 a 同じオブジェクトを参照するため、出力はになり b ます。If Point is a class, the output is 20 because a and b reference the same object. Pointが構造体の場合、出力はになり 10 a ます。への代入に b よって値のコピーが作成され、このコピーはへの後続の代入の影響を受け a.x ません。If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

前述の例では、構造体の 2 つの制限事項が強調されています。The previous example highlights two of the limitations of structs. 1 つめは、構造体全体をコピーすることは通常、オブジェクト参照をコピーするよりも非効率であり、割り当てと値パラメーターの引き渡しは参照型よりも構造体のほうが手がかかるということです。First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. 2 つめは、ref および out パラメーターを除いて、構造体への参照を作成することはできず、そのために構造体を使用できない状況が数多くあるということです。Second, except for ref and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.

配列Arrays

*配列 _ は、計算されたインデックスを通じてアクセスされる多数の変数を含むデータ構造です。An *array _ is a data structure that contains a number of variables that are accessed through computed indices. 配列に含まれる変数は、配列の *要素* とも呼ばれ、すべて同じ型であり、この型は配列の _ 要素型* と呼ばれます。The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the _ element type* of the array.

配列型は参照型で、配列変数の宣言は、配列インスタンスへの参照の領域を確保します。Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. 実際の配列インスタンスは、実行時に演算子を使用して動的に作成され new ます。Actual array instances are created dynamically at run-time using the new operator. new 操作によって、新しい配列インスタンスの 長さ が指定され、それはインスタンスの有効期間中は固定です。The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. 配列の要素のインデックスは、0 から Length - 1 までです。The indices of the elements of an array range from 0 to Length - 1. new 演算子は配列の要素を自動的に既定値に初期化します。たとえば、すべての数値型はゼロ、すべての参照型は null です。The new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

次の例では、int 要素の配列を作成し、その配列を初期化し、配列の内容を出力します。The following example creates an array of int elements, initializes the array, and prints out the contents of the array.

using System;

class Test
{
    static void Main() {
        int[] a = new int[10];
        for (int i = 0; i < a.Length; i++) {
            a[i] = i * i;
        }
        for (int i = 0; i < a.Length; i++) {
            Console.WriteLine("a[{0}] = {1}", i, a[i]);
        }
    }
}

この例では、*1 次元配列 _ を作成して操作します。This example creates and operates on a *single-dimensional array . C# では、"*多次元配列*_" もサポートされます。C# also supports multi-dimensional arrays. 配列型の次元数は、配列型の _ ランク* とも呼ばれ、配列型の角かっこの間に記述されたコンマの数に1を加えたものです。The number of dimensions of an array type, also known as the _ rank* of the array type, is one plus the number of commas written between the square brackets of the array type. 次の例では、1次元、2次元、および3次元配列を割り当てます。The following example allocates a one-dimensional, a two-dimensional, and a three-dimensional array.

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

a1 配列は 10 の要素、a2 配列は 50 (10 × 5) の要素、a3 配列は 100 (10 × 5 × 2) の要素を含みます。The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

配列の要素型には、配列型を含む任意の型を指定できます。The element type of an array can be any type, including an array type. 配列型の要素を持つ配列は、ジャグ配列 と呼ばれることがあります。要素の配列の長さがすべて同じである必要がないからです。An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays do not all have to be the same. 次の例では、int の配列の配列を割り当てます。The following example allocates an array of arrays of int:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

最初の行で 3 つの要素を持つ配列を作成しますが、各々は int[] 型で null 初期値を持ちます。The first line creates an array with three elements, each of type int[] and each with an initial value of null. それ以降の行では、3 つの要素を、それぞれ異なる長さの配列インスタンスへの参照で初期化します。The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

new 演算子では、配列要素の初期値を、区切り記号 { および } のあいだに記述された式の一覧である 配列初期化子 を使用して指定することができます。The new operator permits the initial values of the array elements to be specified using an array initializer, which is a list of expressions written between the delimiters { and }. 次の例は、int[] を割り当て 3 つの要素で初期化します。The following example allocates and initializes an int[] with three elements.

int[] a = new int[] {1, 2, 3};

配列の長さは、との間の式の数から推論されることに注意して { } ください。Note that the length of the array is inferred from the number of expressions between { and }. ローカル変数およびフィールド宣言をさらに短縮して、配列型を再起動する必要がないようにできます。Local variable and field declarations can be shortened further such that the array type does not have to be restated.

int[] a = {1, 2, 3};

前述の例はどちらも、次の例と同等です。Both of the previous examples are equivalent to the following:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

インターフェイスInterfaces

"インターフェイス" は、クラスと構造体によって実装できるコントラクトを定義します。An interface defines a contract that can be implemented by classes and structs. 1 つのインターフェイスには、メソッド、プロパティ、イベント、およびインデクサーが含まれる場合があります。An interface can contain methods, properties, events, and indexers. インターフェイスでは、定義するメンバーの実装は行いません。インターフェイスを実装するクラスまたは構造体によって提供される必要があるメンバーを指定するだけです。An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

インターフェイスは 多重継承 を使用する場合があります。Interfaces may employ multiple inheritance. 次の例では、インターフェイス IComboBoxITextBoxIListBox の両方から継承します。In the following example, the interface IComboBox inherits from both ITextBox and IListBox.

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

クラスと構造体は、複数のインターフェイスを実装できます。Classes and structs can implement multiple interfaces. 次の例では、クラス EditBoxIControlIDataBound の両方を実装しています。In the following example, the class EditBox implements both IControl and IDataBound.

interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox: IControl, IDataBound
{
    public void Paint() {...}
    public void Bind(Binder b) {...}
}

クラスまたは構造体が特定のインターフェイスを実装する場合、そのクラスまたは構造体のインスタンスはそのインターフェイス型に暗黙的に変換できます。When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. 次に例を示します。For example

EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

インスタンスが特定のインターフェイスを静的に実装しないとわかっている場合は、動的な型キャストを使用できます。In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. たとえば、次のステートメントは動的な型キャストを使用して、オブジェクト IControl とインターフェイスの実装を取得 IDataBound します。For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. オブジェクトの実際の型はであるため、 EditBox キャストは成功します。Because the actual type of the object is EditBox, the casts succeed.

object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

前のクラスでは、インターフェイスからの EditBox Paint メソッドとインターフェイスからのメソッドが、 IControl Bind IDataBound メンバーを使用して実装されてい public ます。In the previous EditBox class, the Paint method from the IControl interface and the Bind method from the IDataBound interface are implemented using public members. C# では、 明示的なインターフェイスメンバーの実装 もサポートしています。これを使用すると、クラスまたは構造体がメンバーを作成するのを回避でき public ます。C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. 明示的なインターフェイス メンバーの実装は、完全修飾のインターフェイス メンバー名を使用して書き込まれます。An explicit interface member implementation is written using the fully qualified interface member name. たとえば、EditBox クラスは、次のように明示的なインターフェイス メンバーの実装を使用して、IControl.Paint メソッドおよび IDataBound.Bind メソッドを実装できます。For example, the EditBox class could implement the IControl.Paint and IDataBound.Bind methods using explicit interface member implementations as follows.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}

明示的なインターフェイス メンバーは、インターフェイス型を経由してのみアクセスできます。Explicit interface members can only be accessed via the interface type. たとえば、 IControl.Paint 前のクラスによって提供されるの実装は、 EditBox 最初に参照を EditBox インターフェイス型に変換することによってのみ呼び出すことができ IControl ます。For example, the implementation of IControl.Paint provided by the previous EditBox class can only be invoked by first converting the EditBox reference to the IControl interface type.

EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok

列挙型Enums

列挙型 は、一連の名前付き定数を使用する固有の値の型です。An enum type is a distinct value type with a set of named constants. 次の例では、、、 Color およびという3つの定数値を持つという名前の列挙型を宣言して使用し Red Green Blue ます。The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

class Test
{
    static void PrintColor(Color color) {
        switch (color) {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
            case Color.Blue:
                Console.WriteLine("Blue");
                break;
            default:
                Console.WriteLine("Unknown color");
                break;
        }
    }

    static void Main() {
        Color c = Color.Red;
        PrintColor(c);
        PrintColor(Color.Blue);
    }
}

各列挙型には、列挙型の 基になる型 と呼ばれる対応する整数型があります。Each enum type has a corresponding integral type called the underlying type of the enum type. 基になる型を明示的に宣言しない列挙型には、の基になる型があり int ます。An enum type that does not explicitly declare an underlying type has an underlying type of int. 列挙型のストレージ形式と使用可能な値の範囲は、基になる型によって決まります。An enum type's storage format and range of possible values are determined by its underlying type. 列挙型が受け取ることができる値のセットは、列挙型のメンバーによって制限されません。The set of values that an enum type can take on is not limited by its enum members. 特に、列挙型の基になる型の任意の値を列挙型にキャストし、その列挙型の個別の有効な値にすることができます。In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

次の例では、基になる型を持つという名前の列挙型を宣言 Alignment sbyte しています。The following example declares an enum type named Alignment with an underlying type of sbyte.

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}

前の例で示したように、列挙型メンバーの宣言には、メンバーの値を指定する定数式を含めることができます。As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. 各列挙型メンバーの定数値は、列挙型の基になる型の範囲内である必要があります。The constant value for each enum member must be in the range of the underlying type of the enum. 列挙メンバー宣言によって値が明示的に指定されていない場合、メンバーには値 0 (列挙型の最初のメンバーの場合)、またはテキスト形式の前の列挙型メンバーの値に1を加えた値が与えられます。When an enum member declaration does not explicitly specify a value, the member is given the value zero (if it is the first member in the enum type) or the value of the textually preceding enum member plus one.

列挙値は、型キャストを使用して、整数値に変換できます。Enum values can be converted to integral values and vice versa using type casts. 次に例を示します。For example

int i = (int)Color.Blue;        // int i = 2;
Color c = (Color)2;             // Color c = Color.Blue;

任意の列挙型の既定値は、列挙型に変換された整数値0です。The default value of any enum type is the integral value zero converted to the enum type. 変数が既定値に自動的に初期化される場合、これは列挙型の変数に指定された値になります。In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. 列挙型の既定値を簡単に使用できるようにするために、リテラルは 0 暗黙的に任意の列挙型に変換されます。In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. したがって、次の例も許可されます。Thus, the following is permitted.

Color c = 0;

代理人Delegates

"デリゲート型" は、特定のパラメーター リストおよび戻り値を使用してメソッドへの参照を表します。A delegate type represents references to methods with a particular parameter list and return type. デリゲートを使用すれば、変数に割り当ててパラメーターとして渡すことのできるエンティティとして、メソッドを処理できます。Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. デリゲートはまた、他のいくつかの言語にみられる関数ポインターの概念に似ていますが、関数ポインターとは異なり、デリゲートはオブジェクト指向でタイプ セーフです。Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

次の例では、Function という名前のデリゲート型を宣言して使用します。The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

    public Multiplier(double factor) {
        this.factor = factor;
    }

    public double Multiply(double x) {
        return x * factor;
    }
}

class Test
{
    static double Square(double x) {
        return x * x;
    }

    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void Main() {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Function デリゲート型のインスタンスは、double 引数を取得して double 値を返す任意のメソッドを参照できます。An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Apply メソッドは、指定された Functiondouble[] の要素に適用し、double[] を結果とともに返します。The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Main メソッドでは、Applydouble[] に 3 つの異なる関数を適用するために使用されます。In the Main method, Apply is used to apply three different functions to a double[].

デリゲートは、静的メソッド (前述の例の SquareMath.Sin など) またはインスタンス メソッド (前述の例の m.Multiply など) のいずれかを参照できます。A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). インスタンス メソッドを参照するデリゲートはまた、特定のオブジェクトを参照し、インスタンス メソッドがデリゲートから呼び出されると、そのオブジェクトは呼び出しで this になります。A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

その場で作成される「インライン メソッド」である匿名関数を使用してデリゲートを作成することもできます。Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. 匿名関数では、周囲のメソッドのローカル変数を確認できます。Anonymous functions can see the local variables of the surrounding methods. このため、上記の乗数の例は、クラスを使用せずにより簡単に記述でき Multiplier ます。Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

デリゲートの興味深く有用な点は、参照するメソッドのクラスを把握せず必要ともしないことです。重要なのは、参照されるメソッドは同じパラメーターを持ち、デリゲートとして型を返すということです。An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.

属性Attributes

C# プログラムにおける型、メンバー、およびその他のエンティティは、動作の特定の側面を制御する修飾子をサポートします。Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. たとえばメソッドのアクセシビリティは、publicprotectedinternal、および private 修飾子を使用して制御されます。For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C# はこの機能を一般化し、宣言情報のユーザー定義型をプログラム エンティティに追加して実行時に取得できるようにします。C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. プログラムでは、 属性 を定義して使用することによって、この追加の宣言情報を指定します。Programs specify this additional declarative information by defining and using attributes.

次の例では、プログラムのエンティティに配置して関連するドキュメントへのリンクを提供することができる HelpAttribute 属性を宣言しています。The following example declares a HelpAttribute attribute that can be placed on program entities to provide links to their associated documentation.

using System;

public class HelpAttribute: Attribute
{
    string url;
    string topic;

    public HelpAttribute(string url) {
        this.url = url;
    }

    public string Url {
        get { return url; }
    }

    public string Topic {
        get { return topic; }
        set { topic = value; }
    }
}

すべての属性クラスは System.Attribute 、.NET Framework によって提供される基本クラスから派生します。All attribute classes derive from the System.Attribute base class provided by the .NET Framework. 属性は、関連付けられた宣言の直前に、名前を任意の変数とともに角かっこで囲んで与えることにより、適用できます。Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. 属性の名前がで終わる場合は、 Attribute 属性が参照されているときに名前のその部分を省略できます。If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. たとえば、HelpAttribute 属性は次のように使用できます。For example, the HelpAttribute attribute can be used as follows.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

この例では、をクラスに、別のをクラスの HelpAttribute Widget メソッドにアタッチし HelpAttribute Display ます。This example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. 属性クラスのパブリック コンストラクターは、属性がプログラム エンティティにアタッチされたときに提供する必要がある情報を制御します。The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. その属性クラスのパブリックの読み取り/書き込みプロパティを参照することにより (Topic プロパティへの参照のような)、追加情報を提供することができます。Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

次の例は、特定のプログラムエンティティの属性情報を、リフレクションを使用して実行時に取得する方法を示しています。The following example shows how attribute information for a given program entity can be retrieved at run-time using reflection.

using System;
using System.Reflection;

class Test
{
    static void ShowHelp(MemberInfo member) {
        HelpAttribute a = Attribute.GetCustomAttribute(member,
            typeof(HelpAttribute)) as HelpAttribute;
        if (a == null) {
            Console.WriteLine("No help for {0}", member);
        }
        else {
            Console.WriteLine("Help for {0}:", member);
            Console.WriteLine("  Url={0}, Topic={1}", a.Url, a.Topic);
        }
    }

    static void Main() {
        ShowHelp(typeof(Widget));
        ShowHelp(typeof(Widget).GetMethod("Display"));
    }
}

リフレクションによって特定の属性が要求されると、プログラム ソースで提供される情報で属性クラスのコンストラクターが呼び出され、結果の属性インスタンスが返されます。When a particular attribute is requested through reflection, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. 追加情報がプロパティを通じて提供された場合、属性インスタンスが返される前に、これらのプロパティは指定された値に設定されます。If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.