공용 형식 시스템의 값 형식
업데이트: 2007년 11월
대부분의 프로그래밍 언어에 정수나 부동 소수점 숫자와 같은 기본 제공 데이터 형식이 있으며 이러한 데이터 형식은 인수로 전달될 때, 즉 값으로 전달될 때 복사됩니다. .NET Framework에서는 이를 값 형식이라고 합니다. 런타임에서는 다음과 같은 두 가지 값 형식을 지원합니다.
기본 제공 값 형식
.NET Framework에는 프로그래밍 언어에서 사용하는 기본 데이터 형식에 대응하고 동일한 기능을 갖는 System.Int32와 System.Boolean 같은 기본 제공 값 형식이 정의되어 있습니다.
사용자 정의 값 형식
System.ValueType 또는 System.Enum에서 파생되는 고유의 값 형식을 정의하는 방법이 제공될 것입니다. 두 개의 부동 소수점 숫자를 사용하는 복소수 같이 작은 값을 나타내는 형식을 정의하는 경우, 이를 값 형식으로 정의하면 값으로 전달할 수 있어 매우 효율적입니다. 정의하는 형식을 참조로 전달하는 것이 더 효과적인 경우에는 형식을 클래스로 정의해야 합니다.
열거형에 특정한 내용은 공용 형식 시스템의 열거형을 참조하십시오.
값 형식은 기본 형식처럼 효율적으로 저장할 수 있고, 값 형식 자체에 정의된 메서드는 물론 System.Object 및 System.ValueType 클래스에 정의된 가상 메서드를 비롯하여 메서드를 값 형식에 대해 호출할 수 있습니다. 값 형식의 인스턴스를 만들어 매개 변수로 전달하고 지역 변수로 저장하거나 다른 값 형식 또는 개체의 필드에 저장할 수 있습니다. 값 형식을 사용하면 클래스의 인스턴스를 저장해야 하는 부담이 없고 생성자가 필요 없습니다.
런타임에서는 각 값 형식에 대해 상태 및 동작이 동일한 boxed 형식 클래스를 제공합니다. 일부 언어에서는 boxed 형식이 필요한 때 별도의 구문을 사용해야 하지만 그 밖의 언어에서는 필요할 때 boxed 형식을 자동으로 사용합니다. 값 형식을 정의하면 boxed 형식과 unboxed 형식이 모두 정의됩니다.
값 형식에서는 필드, 속성 및 이벤트를 가질 수 있으며, 정적 메서드와 비정적 메서드를 가질 수도 있습니다. boxed인 값 형식은 System.ValueType에서 가상 메서드를 상속하며 인터페이스를 구현하지 않거나 한 개 이상의 인터페이스를 구현할 수 있습니다.
값 형식은 봉인되어 있으므로 이 형식에서 다른 형식을 파생할 수 없습니다. 그러나 값 형식에서 직접 가상 메서드를 정의하여 이 메서드를 boxed 또는 unboxed 형식에서 호출할 수 있습니다. 값 형식에서 다른 형식을 파생할 수는 없지만, 가상이 아닌 메서드 또는 정적 메서드를 사용하는 것보다 가상 메서드를 사용하는 것이 나은 언어를 사용하는 경우에는 값 형식에 가상 메서드를 정의할 수도 있습니다.
다음 예제에서는 복소수를 위한 값 형식을 만드는 방법을 보여 줍니다.
Option Strict
Option Explicit
Imports System
' Value type definition for a complex number representation.
Public Structure Complex
Public r, i As Double
' Constructor.
Public Sub New(r As Double, i As Double)
Me.r = r
Me.i = i
End Sub
' Returns one divided by the current value.
Public ReadOnly Property Reciprocal() As Complex
Get
If r = 0.0 And i = 0.0 Then
Throw New DivideByZeroException()
End If
Dim div As Double = r * r + i * i
Return New Complex(r / div, -i / div)
End Get
End Property
' Conversion methods.
Public Shared Function ToDouble(a As Complex) As Double
Return a.r
End Function
Public Shared Function ToComplex(r As Double) As Complex
Return New Complex(r, 0.0)
End Function
' Basic unary methods.
Public Shared Function ToPositive(a As Complex) As Complex
Return a
End Function
Public Shared Function ToNegative(a As Complex) As Complex
Return New Complex(-a.r, -a.i)
End Function
' Basic binary methods for addition, subtraction, multiplication, and division.
Public Shared Function Add(a As Complex, b As Complex) As Complex
Return New Complex(a.r + b.r, a.i + b.i)
End Function
Public Shared Function Subtract(a As Complex, b As Complex) As Complex
Return New Complex(a.r - b.r, a.i - b.i)
End Function
Public Shared Function Multiply(a As Complex, b As Complex) As Complex
Return New Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r)
End Function
Public Shared Function Divide(a As Complex, b As Complex) As Complex
Return Multiply(a, b.Reciprocal)
End Function
' Override the ToString method so the value appears in write statements.
Public Overrides Function ToString As String
Return String.Format("({0}+{1}i)", r, i)
End Function
End Structure
' Entry point.
Public Class ValueTypeSample
Public Shared Sub Main()
Dim a As New Complex(0, 1)
Dim b As New Complex(0, - 2)
Console.WriteLine()
Console.WriteLine("a = " & a.ToString)
Console.WriteLine("b = " & b.ToString)
Console.WriteLine()
Console.WriteLine("a + b = " & Complex.Add(a, b).ToString)
Console.WriteLine("a - b = " & Complex.Subtract(a, b).ToString)
Console.WriteLine("a * b = " & Complex.Multiply(a, b).ToString)
Console.WriteLine("a / b = " & Complex.Divide(a, b).ToString)
Console.WriteLine()
Console.WriteLine("(double)a = " & Complex.ToDouble(a).ToString)
Console.WriteLine("(Complex)5 = " & Complex.ToComplex(5).ToString)
End Sub
End Class
using System;
// Value type definition for a complex number representation.
public struct Complex
{
public double r, i;
// Constructor.
public Complex(double r, double i) { this.r = r; this.i = i; }
// Returns one divided by the current value.
public Complex Reciprocal
{
get
{
if (r == 0d && i == 0d)
throw new DivideByZeroException();
double div = r*r + i*i;
return new Complex(r/div, -i/div);
}
}
// Conversion operators.
public static explicit operator double(Complex a)
{
return a.r;
}
public static implicit operator Complex(double r)
{
return new Complex(r,0d);
}
// Basic unary operators.
public static Complex operator + (Complex a)
{
return a;
}
public static Complex operator - (Complex a)
{
return new Complex(-a.r, -a.i);
}
// Basic binary operators for addition, subtraction, multiplication, and division.
public static Complex operator + (Complex a, Complex b)
{
return new Complex(a.r + b.r, a.i + b.i);
}
public static Complex operator - (Complex a, Complex b)
{
return new Complex(a.r - b.r, a.i - b.i);
}
public static Complex operator * (Complex a, Complex b)
{
return new Complex(a.r*b.r - a.i*b.i, a.r*b.i + a.i*b.r);
}
public static Complex operator / (Complex a, Complex b)
{
return a * b.Reciprocal;
}
// Override the ToString method so the value appears in write statements.
public override string ToString() {
return String.Format("({0}+{1}i)", r, i);
}
}
// Entry point.
public class ValueTypeSample
{
public static void Main()
{
Complex a = new Complex(0, 1);
Complex b = new Complex(0, -2);
Console.WriteLine();
Console.WriteLine("a = " + a);
Console.WriteLine("b = " + b);
Console.WriteLine();
Console.WriteLine("a + b = " + (a+b));
Console.WriteLine("a - b = " + (a-b));
Console.WriteLine("a * b = " + (a*b));
Console.WriteLine("a / b = " + (a/b));
Console.WriteLine();
Console.WriteLine("(double)a = " + (double)a);
Console.WriteLine("(Complex)5 = " + (Complex)5);
}
}
이 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
a = (0+1i)
b = (0+-2i)
a + b = (0+-1i)
a - b = (0+3i)
a * b = (2+0i)
a / b = (-0.5+0i)
(double)a = 0
(Complex)5 = (5+0i)
참고 항목
개념
Visual Studio의 .NET Framework 클래스 라이브러리 소개