공용 형식 시스템 개요
업데이트: 2007년 11월
이 단원에서는 언어별 공용 형식 시스템 구현을 이해하고 사용하는 데 도움이 되도록 개념을 설명하고 관련 용어를 정의합니다.
형식 분류
공용 형식 시스템에서는 아래와 같은 두 가지 범주의 형식을 지원하며 각 범주는 다시 하위 범주로 나뉩니다.
값 형식
값 형식에서는 데이터를 직접 포함하며, 값 형식의 인스턴스는 스택에 할당되거나 구조에서 인라인으로 할당됩니다. 값 형식의 종류로는 런타임에서 구현하는 기본 제공 형식, 사용자 정의 형식 및 열거 형식이 있습니다. 기본으로 제공되는 값 형식의 목록을 보려면 .NET Framework 클래스 라이브러리를 참조하십시오.
참조 형식
참조 형식은 값의 메모리 주소에 대한 참조를 저장하며 힙에 할당됩니다. 참조 형식의 종류에는 자기 설명 형식, 포인터 형식 및 인터페이스 형식이 있습니다. 참조 형식의 종류는 자기 설명 형식의 값을 통해 확인할 수 있습니다. 자기 설명 형식은 배열 형식과 클래스 형식으로 다시 나뉩니다. 클래스 형식에는 사용자 정의 클래스, boxed 값 형식 및 대리자가 있습니다.
값 형식의 변수에는 각기 고유의 데이터 복사본이 있으므로 한 변수에 대해 작업할 때 다른 변수는 영향을 받지 않습니다. 참조 형식의 변수에서는 같은 개체를 참조할 수 있으므로, 한 변수에 대한 작업으로 인해 다른 변수에서 참조하는 동일한 개체가 영향을 받을 수도 있습니다.
모든 형식은 System.Object 기본 형식에서 파생됩니다.
다음 예제에서는 참조 형식과 값 형식 간의 차이점을 보여 줍니다.
Class Class1
Public Value As Integer = 0
End Class 'Class1
Class Test
Shared Sub Main()
Dim val1 As Integer = 0
Dim val2 As Integer = val1
val2 = 123
Dim ref1 As New Class1()
Dim ref2 As Class1 = ref1
ref2.Value = 123
Console.WriteLine("Values: {0}, {1}", val1, val2)
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value)
End Sub 'Main
End Class 'Test
using System;
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
int val1 = 0;
int val2 = val1;
val2 = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
이 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
Values: 0, 123
Refs: 123, 123
아래의 다이어그램에서는 다양한 이들 형식 간의 관계를 보여 줍니다. 형식의 하위 범주가 있더라도 그 인스턴스가 단순히 값 형식 또는 자기 설명 형식일 수도 있습니다.
형식 분류
각 형식에 대한 자세한 내용은 값 형식, 열거형, 클래스, 대리자, 배열, 인터페이스 및 포인터를 참조하십시오.
값 및 개체
값은 데이터를 이진법으로 나타낸 것이고 이러한 데이터는 형식을 통해 해석됩니다. 값 형식은 형식을 나타내는 데이터에 대한 이진 표시로 직접 저장됩니다. 참조 형식의 값은 해당 형식의 데이터를 나타내는 일련의 비트 위치를 의미합니다.
모든 값에는 값의 표시 및 그 값에 대해 정의된 작업을 완전하게 정의하는 정확한 형식이 있습니다. 자기 설명 형식의 값을 개체라고 합니다. 개체의 경우에는 값을 검사하여 정확한 형식을 확인할 수 있지만 값 형식이나 포인터 형식의 경우는 이를 확인할 수 없습니다. 값 하나가 둘 이상의 형식에 해당할 수도 있습니다. 예를 들어, 인터페이스를 구현하는 형식의 값은 해당 인터페이스 형식의 값이기도 합니다. 마찬가지로, 기본 형식에서 파생된 형식의 값은 해당 기본 형식의 값이기도 합니다.
형식 및 어셈블리
런타임에서는 어셈블리를 사용하여 형식을 찾고 로드합니다. 어셈블리 매니페스트에는 어셈블리의 범위 내에서 만들어진 모든 형식 참조를 확인하기 위해 런타임에서 사용하는 정보가 들어 있습니다.
런타임에 들어 있는 형식 이름은 두 가지 논리 부분 즉, 어셈블리 이름과 어셈블리 내 형식의 이름으로 구성됩니다. 이름은 같지만 서로 다른 어셈블리에 포함된 두 형식은 두 개의 개별 형식으로 정의됩니다.
개발자에게 표시되는 이름 범위와 런타임 시스템에서 인식하는 이름 범위 사이의 일관성은 어셈블리를 통해 유지됩니다. 개발자는 형식을 어셈블리 컨텍스트에서 작성하며, 개발자가 만드는 어셈블리의 내용에 의해 런타임에 사용할 수 있는 이름 범위가 설정됩니다.
형식 및 네임스페이스
런타임 관점에서 보면 네임스페이스는 형식 이름의 컬렉션에 불과합니다. 특정 언어에는 개발자가 논리적 형식 그룹을 만드는 데 도움이 되는 구조와 이에 상응하는 구문이 있을 수 있지만 이 구조는 런타임에서 형식을 바인딩할 때 사용되지 않습니다. 따라서 Object와 String 클래스는 모두 System 네임스페이스의 일부이지만 런타임에서는 각 형식의 전체 이름인 System.Object와 System.String만 인식합니다.
System.Collections 및 System.Windows.Forms와 같이 서로 다른 두 개의 계층적 네임스페이스에서 가져온 것처럼 보이는 형식을 노출하는 단일 어셈블리를 만들 수 있습니다. 이름에 MyDll.MyClass가 포함된 형식을 내보내는 두 개의 어셈블리를 만들 수도 있습니다.
어셈블리에 있는 형식이 속하는 계층적 네임스페이스를 나타내는 도구를 만드는 경우, 도구에서는 단일 어셈블리 또는 어셈블리 그룹의 형식을 나열하고 형식 이름을 구문 분석하여 계층적 관계를 도출해야 합니다.