개체 - 형식의 인스턴스 만들기

클래스 또는 구조체 정의는 형식이 수행할 수 있는 작업을 지정하는 청사진과 비슷합니다. 개체는 기본적으로 청사진에 따라 구성 및 할당된 메모리 블록입니다. 프로그램에서 동일한 클래스의 많은 개체를 만들 수 있습니다. 개체를 인스턴스라고도 하며, 명명된 변수나 배열 또는 컬렉션에 저장할 수 있습니다. 클라이언트 코드는 이러한 변수를 사용하여 메서드를 호출하고 개체의 공용 속성에 액세스하는 코드입니다. C#과 같은 개체 지향 언어에서 일반적인 프로그램은 동적으로 상호 작용하는 여러 개체로 구성됩니다.

참고 항목

정적 형식은 여기에 설명된 것과 다르게 동작합니다. 자세한 내용은 static 클래스 및 static 클래스 멤버를 참조하세요.

구조체 인스턴스 및 클래스 인스턴스

클래스는 참조 형식이므로 클래스 개체의 변수는 관리되는 힙의 개체 주소에 대한 참조를 포함합니다. 동일한 형식의 두 번째 변수가 첫 번째 변수에 할당된 경우 두 변수 모두 해당 주소의 개체를 참조합니다. 이 점은 이 문서의 뒷부분에서 자세히 설명합니다.

클래스 인스턴스는 new 연산자를 사용하여 생성됩니다. 다음 예제에서 Person은 형식이고 person1person2는 해당 형식의 인스턴스 또는 개체입니다.

using System;

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);
    }
}
/*
    Output:
    person1 Name = Leopold Age = 6
    person2 Name = Molly Age = 16
    person1 Name = Molly Age = 16
*/

구조체는 값 형식이므로 구조체 개체의 변수는 전체 개체의 복사본을 포함합니다. 다음 예제와 같이 new 연산자를 사용하여 구조체 인스턴스를 만들 수도 있지만 필수는 아닙니다.

using System;

namespace 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);
        }
    }
    /*
        Output:
        p1 Name = Alex Age = 9
        p2 Name = Spencer Age = 7
        p1 Name = Alex Age = 9
    */
}

p1p2 둘 다에 대한 메모리가 스레드 스택에서 할당됩니다. 해당 메모리는 선언된 형식 또는 메서드와 함께 회수됩니다. 이는 할당 시 구조체가 복사되는 이유 중 하나입니다. 반면, 클래스 인스턴스에 할당된 메모리는 개체에 대한 모든 참조가 범위를 벗어날 때 공용 언어 런타임에 의해 자동으로 회수(가비지 수집)됩니다. C++에서처럼 클래스 개체를 결정적으로 삭제할 수는 없습니다. .NET의 가비지 수집에 대한 자세한 내용은 가비지 수집을 참조하세요.

참고 항목

관리되는 힙의 메모리 할당 및 할당 취소는 공용 언어 런타임에서 고도로 최적화되어 있습니다. 대부분의 경우 힙에서 클래스 인스턴스를 할당하는 경우와 스택에서 구조체 인스턴스를 할당하는 경우의 성능 차이는 크지 않습니다.

개체 ID와 값 같음 비교

두 개체가 같은지를 비교하는 경우 먼저 두 변수가 메모리에서 동일한 개체를 나타내는지 또는 해당 필드 값이 하나 이상 같은지를 알고 싶은 것인지 구분해야 합니다. 값을 비교하려는 경우 개체가 값 형식(구조체) 또는 참조 형식(클래스, 대리자, 배열)의 인스턴스인지 고려해야 합니다.

  • 두 클래스 인스턴스가 메모리의 동일한 위치를 참조하는지 확인하려면(즉, ID가 같음) 정적 Object.Equals 메서드를 사용합니다. System.Object은 사용자 정의 구조체 및 클래스를 포함하여 모든 값 형식 및 참조 형식에 대한 암시적 기본 클래스입니다.

  • 두 구조체 인스턴스의 인스턴스 필드 값이 같은지 확인하려면 ValueType.Equals 메서드를 사용합니다. 모든 구조체가 System.ValueType에서 암시적으로 상속하기 때문에 다음 예제와 같이 개체에서 직접 메서드를 호출합니다.

    // 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 = new Person("", 42);
    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.
    

    EqualsSystem.ValueType 구현에서는 경우에 따라 boxing 및 리플렉션을 사용합니다. 형식에 따라 효율적인 같음 알고리즘을 제공하는 방법에 대한 자세한 내용은 형식의 값 같음을 정의하는 방법을 참조하세요. 레코드는 같음을 위해 값 의미 체계를 사용하는 참조 형식입니다.

  • 두 클래스 인스턴스의 필드 값이 같은지 확인하기 위해 Equals 메서드 또는 == 연산자를 사용할 수 있습니다. 그러나 클래스가 해당 형식의 개체에 대해 "같음"이 무엇을 의미하는지의 사용자 지정 정의를 제공하도록 재정의 또는 오버로드한 경우에만 사용합니다. 클래스는 IEquatable<T> 인터페이스 또는 IEqualityComparer<T> 인터페이스도 구현할 수 있습니다. 두 인터페이스 모두 값이 같은지를 테스트하는 데 사용할 수 있는 메서드를 제공합니다. Equals을 재정의하는 고유한 클래스를 디자인하는 경우 형식의 값 같음을 정의하는 방법Object.Equals(Object)에 명시된 지침을 따라야 합니다.

자세한 내용은 다음에서 확인합니다.