オブジェクト (C# プログラミング ガイド)Objects (C# Programming Guide)

クラスまたは構造体の定義は、型の動作を指定する設計図に似ています。A class or struct definition is like a blueprint that specifies what the type can do. オブジェクトは基本的に、設計図に従って割り当てられて構成されたメモリのブロックです。An object is basically a block of memory that has been allocated and configured according to the blueprint. プログラムでは、同じクラスのオブジェクトを多数作成できます。A program may create many objects of the same class. オブジェクトはインスタンスとも呼ばれ、名前付きの変数または配列やコレクションに格納できます。Objects are also called instances, and they can be stored in either a named variable or in an array or collection. クライアント コードとは、これらの変数を使ってメソッドを呼び出し、オブジェクトのパブリック プロパティにアクセスするコードです。Client code is the code that uses these variables to call the methods and access the public properties of the object. C# などのオブジェクト指向言語では、一般的なプログラムは動的に対話する複数のオブジェクトで構成されています。In an object-oriented language such as C#, a typical program consists of multiple objects interacting dynamically.

注意

静的な型の動作方法は、ここで説明する動作方法とは異なります。Static types behave differently than what is described here. 詳細については、「静的クラスと静的クラス メンバー」を参照してください。For more information, see Static Classes and Static Class Members.

構造体インスタンスとクラス インスタンスStruct Instances vs. Class Instances

クラスは参照型であるため、クラスのオブジェクトの変数は、マネージド ヒープ上のオブジェクトのアドレスへの参照を保持します。Because classes are reference types, a variable of a class object holds a reference to the address of the object on the managed heap. 同じ型の 2 番目のオブジェクトが最初のオブジェクトに割り当てられた場合、両方の変数がそのアドレスにあるオブジェクトを参照します。If a second object of the same type is assigned to the first object, then both variables refer to the object at that address. この点については、後で詳しく説明します。This point is discussed in more detail later in this topic.

クラスのインスタンスは、new 演算子を使って作成されます。Instances of classes are created by using the new operator. 次の例では、Person が型で、person1person 2 がその型のインスタンスつまりオブジェクトです。In the following example, Person is the type and person1 and person 2 are instances, or objects, of that type.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    // Other properties, methods, events...
}

class Program
{
    static void Main()
    {
        Person person1 = new Person("Leopold", 6);
        Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

        // Declare new person, assign person1 to it.
        Person person2 = person1;

        // Change the name of person2, and person1 also changes.
        person2.Name = "Molly";
        person2.Age = 16;

        Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age);
        Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();

    }
}
/*
    Output:
    person1 Name = Leopold Age = 6
    person2 Name = Molly Age = 16
    person1 Name = Molly Age = 16
*/

構造体は値型であるため、構造体オブジェクトの変数はオブジェクト全体のコピーを保持します。Because structs are value types, a variable of a struct object holds a copy of the entire object. 構造体のインスタンスも new 演算子を使って作成できますが、次の例で示すように、これは必要ではありません。Instances of structs can also be created by using the new operator, but this is not required, as shown in the following example:

public struct Person
{
    public string Name;
    public int Age;
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

public class Application
{
    static void Main()
    {
        // Create  struct instance and initialize by using "new".
        // Memory is allocated on thread stack.
        Person p1 = new Person("Alex", 9);
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Create  new struct object. Note that  struct can be initialized
        // without using "new".
        Person p2 = p1;

        // Assign values to p2 members.
        p2.Name = "Spencer";
        p2.Age = 7;
        Console.WriteLine("p2 Name = {0} Age = {1}", p2.Name, p2.Age);

        // p1 values remain unchanged because p2 is  copy.
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/*
  Output:
    p1 Name = Alex Age = 9
    p2 Name = Spencer Age = 7
    p1 Name = Alex Age = 9
*/

p1p2 のメモリはどちらも、スレッドのスタックに割り当てられます。The memory for both p1 and p2 is allocated on the thread stack. そのメモリは、それが宣言されている型またはメソッドと共に解放されます。That memory is reclaimed along with the type or method in which it is declared. これは、割り当て時に構造体がコピーされる理由の 1 です。This is one reason why structs are copied on assignment. これに対し、クラスのインスタンスに割り当てられたメモリは、そのオブジェクトに対するすべての参照がスコープ外になると、共通言語ランタイムによって自動的に解放 (ガベージ コレクション) されます。By contrast, the memory that is allocated for a class instance is automatically reclaimed (garbage collected) by the common language runtime when all references to the object have gone out of scope. C++ のようにクラスのオブジェクトを確定的に破棄することはできません。It is not possible to deterministically destroy a class object like you can in C++. .NET Framework のガベージ コレクションについて詳しくは、「ガベージ コレクション」をご覧ください。For more information about garbage collection in the .NET Framework, see Garbage Collection.

注意

マネージド ヒープ上のメモリの割り当てと解放は、共通言語ランタイムにおいて高度に最適化されています。The allocation and deallocation of memory on the managed heap is highly optimized in the common language runtime. ほとんどの場合、ヒープへのクラス インスタンスの割り当てと、スタックへの構造体インスタンスの割り当てに、パフォーマンス コストの点で大きな違いはありません。In most cases there is no significant difference in the performance cost of allocating a class instance on the heap versus allocating a struct instance on the stack.

オブジェクト ID と値の等価性Object Identity vs. Value Equality

2 つのオブジェクトが等しいかどうかを比較するときは、最初に、2 つの変数がメモリ内の同じオブジェクトを表しているかどうかを知りたいのか、それともオブジェクトの 1 つ以上のフィールドの値が等しいかどうかを知りたいのかを、区別する必要があります。When you compare two objects for equality, you must first distinguish whether you want to know whether the two variables represent the same object in memory, or whether the values of one or more of their fields are equivalent. 値を比較する場合は、オブジェクトが値型 (構造体) のインスタンスか、または参照型 (クラス、デリゲート、配列) のインスタンスかを、検討する必要があります。If you are intending to compare values, you must consider whether the objects are instances of value types (structs) or reference types (classes, delegates, arrays).

  • クラスの 2 つのインスタンスがメモリ内の同じ場所を参照しているかどうか (つまり、同じ ID か) を調べるには、静的な Equals メソッドを使いますTo determine whether two class instances refer to the same location in memory (which means that they have the same identity), use the static Equals method. (System.Object は、ユーザー定義の構造体やクラスを含む、すべての値型と参照型の暗黙の基底クラスです)。(System.Object is the implicit base class for all value types and reference types, including user-defined structs and classes.)

  • 2 つの構造体インスタンスのインスタンス フィールドが同じ値を持つかどうかを調べるには、ValueType.Equals メソッドを使います。To determine whether the instance fields in two struct instances have the same values, use the ValueType.Equals method. すべての構造体は System.ValueType を暗黙的に継承するので、次の例で示すように、オブジェクトで直接メソッドを呼び出します。Because all structs implicitly inherit from System.ValueType, you call the method directly on your object as shown in the following example:

// Person is defined in the previous example.

//public struct Person
//{
//    public string Name;
//    public int Age;
//    public Person(string name, int age)
//    {
//        Name = name;
//        Age = age;
//    }
//}

Person p1 = new Person("Wallace", 75);
Person p2;
p2.Name = "Wallace";
p2.Age = 75;

if (p2.Equals(p1))
    Console.WriteLine("p2 and p1 have the same values.");

// Output: p2 and p1 have the same values.

System.ValueType での Equals の実装は、構造体に存在するフィールドを特定できる必要があるため、リフレクションを使います。The System.ValueType implementation of Equals uses reflection because it must be able to determine what the fields are in any struct. 独自の構造体を作成するときは、Equals メソッドをオーバーライドして、独自の型に固有の効率的な等値アルゴリズムを提供します。When creating your own structs, override the Equals method to provide an efficient equality algorithm that is specific to your type.

  • クラスの 2 つのインスタンスのフィールドの値が等しいかどうかを調べるには、Equals メソッドまたは == 演算子を使用できる場合があります。To determine whether the values of the fields in two class instances are equal, you might be able to use the Equals method or the == operator. ただし、この方法を使用できるのは、その型のオブジェクトにおける "等値" の意味のカスタム定義が、クラスのオーバーライドまたはオーバーロードによって提供されている場合だけです。However, only use them if the class has overridden or overloaded them to provide a custom definition of what "equality" means for objects of that type. クラスは、IEquatable<T> インターフェイスまたは IEqualityComparer<T> インターフェイスを実装することもできます。The class might also implement the IEquatable<T> interface or the IEqualityComparer<T> interface. どちらのインターフェイスも、値の等価性をテストするために使うことができるメソッドを提供します。Both interfaces provide methods that can be used to test value equality. Equals をオーバーライドするクラスをご自分で設計するときは、「方法: 型の値の等価性を定義する」および「Object.Equals(Object)」に記載されているガイドラインに従ってください。When designing your own classes that override Equals, make sure to follow the guidelines stated in How to: Define Value Equality for a Type and Object.Equals(Object).

詳細情報For more information:

関連項目See also