공용 형식 시스템의 값 형식

업데이트: 2007년 11월

대부분의 프로그래밍 언어에 정수나 부동 소수점 숫자와 같은 기본 제공 데이터 형식이 있으며 이러한 데이터 형식은 인수로 전달될 때, 즉 값으로 전달될 때 복사됩니다. .NET Framework에서는 이를 값 형식이라고 합니다. 런타임에서는 다음과 같은 두 가지 값 형식을 지원합니다.

  • 기본 제공 값 형식

    .NET Framework에는 프로그래밍 언어에서 사용하는 기본 데이터 형식에 대응하고 동일한 기능을 갖는 System.Int32System.Boolean 같은 기본 제공 값 형식이 정의되어 있습니다.

  • 사용자 정의 값 형식

    System.ValueType 또는 System.Enum에서 파생되는 고유의 값 형식을 정의하는 방법이 제공될 것입니다. 두 개의 부동 소수점 숫자를 사용하는 복소수 같이 작은 값을 나타내는 형식을 정의하는 경우, 이를 값 형식으로 정의하면 값으로 전달할 수 있어 매우 효율적입니다. 정의하는 형식을 참조로 전달하는 것이 더 효과적인 경우에는 형식을 클래스로 정의해야 합니다.

열거형에 특정한 내용은 공용 형식 시스템의 열거형을 참조하십시오.

값 형식은 기본 형식처럼 효율적으로 저장할 수 있고, 값 형식 자체에 정의된 메서드는 물론 System.ObjectSystem.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)

참고 항목

개념

.NET Framework 클래스 라이브러리 개요

Visual Studio의 .NET Framework 클래스 라이브러리 소개

공용 형식 시스템의 열거형

참조

Object

ValueType

기타 리소스

공용 형식 시스템