다음을 통해 공유


개체(C# 프로그래밍 가이드)

업데이트: 2007년 11월

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

참고:

정적 형식은 여기에서 설명하는 내용과 다르게 동작합니다. 자세한 내용은 정적 클래스 및 정적 클래스 멤버(C# 프로그래밍 가이드)를 참조하십시오.

구조체 인스턴스와 클래스 인스턴스 비교

클래스는 참조 형식이므로 클래스 개체의 변수는 개체 주소에 대한 참조를 관리되는 힙에 유지합니다. 첫 번째 개체에 동일한 형식의 두 번째 개체가 할당되면 두 변수 모두 같은 주소에 있는 개체를 참조합니다. 이 내용에 대해서는 이 항목의 뒷부분에서 자세히 설명합니다.

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

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 a 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}", person2.Name, person2.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
*/

구조체는 값 형식이므로 구조체 개체의 변수는 전체 개체의 복사본을 유지합니다. 다음 예제와 같이 new 연산자를 사용하여 구조체의 인스턴스를 만들 수 있지만 이 연산자가 반드시 필요한 것은 아닙니다.

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 a 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 a new struct object. Note that a 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 a 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
*/

p1 및 p2에 대한 메모리는 스레드 스택에 할당됩니다. 이 메모리는 해당 구조체가 선언된 형식 또는 메서드와 함께 회수됩니다. 이것이 구조체가 할당 시 복사되는 이유 중 하나입니다. 이와 달리 클래스 인스턴스용으로 할당된 메모리는 개체에 대한 모든 참조가 범위를 벗어나면 공용 언어 런타임에 의해 자동으로 회수(가비지 수집)됩니다. 하지만 C++에서와 같이 클래스 개체를 명확하게 삭제할 수는 없습니다. .NET Framework의 가비지 수집에 대한 자세한 내용은 가비지 수집을 참조하십시오.

참고:

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

개체 ID와 값 일치 비교

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

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

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

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.

구조체에서 필드의 내용을 확인할 수 있어야 하므로 Equals의 System.ValueType 구현에서는 리플렉션을 사용합니다. 고유한 구조체를 만들 때 해당 형식과 관련된 효율적인 동일성 비교 알고리즘을 제공하려면 Equals 메서드를 재정의합니다.

관련 단원

자세한 내용은 다음 링크를 참조하십시오.

참고 항목

개념

C# 프로그래밍 가이드

공용 형식 시스템의 값 형식

공용 형식 시스템의 클래스

참조

object(C# 참조)

상속(C# 프로그래밍 가이드)

class(C# 참조)

struct(C# 참조)

new 연산자(C# 참조)