유형 동적 사용

dynamic 형식은 정적 형식이지만 dynamic 형식의 개체가 정적 형식 검사를 건너뜁니다. 대부분의 경우 이 형식은 object 형식을 가지고 있는 것처럼 작동합니다. 컴파일러는 dynamic 요소가 모든 작업을 지원한다고 가정합니다. 따라서 개체가 COM API, IronPython과 같은 동적 언어, HTML DOM(문서 개체 모델), 리플렉션 또는 프로그램의 다른 위치에서 값을 가져오는지 여부를 확인할 필요가 없습니다. 그러나 코드가 유효하지 않으면 런타임 시 오류가 나타납니다.

예를 들어 다음 코드의 인스턴스 메서드 exampleMethod1에 매개 변수가 하나뿐인 경우, 컴파일러는 메서드 ec.exampleMethod1(10, 4)에 대한 첫 번째 호출이 유효하지 않음을 인식합니다. 여기에 인수가 두 개 포함되었기 때문입니다. 호출 시 컴파일러 오류가 발생합니다. dynamic_ec의 형식이 dynamic이므로 컴파일러는 dynamic_ec.exampleMethod1(10, 4) 메서드에 대한 두 번째 호출을 확인하지 않습니다. 따라서 컴파일러 오류가 보고되지 않습니다. 그러나 오류가 무기한 통지를 벗어나는 것은 아닙니다. 런타임에 나타나며 런타임 예외가 발생합니다.

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();
    // The following call to exampleMethod1 causes a compiler error
    // if exampleMethod1 has only one parameter. Uncomment the line
    // to see the error.
    //ec.exampleMethod1(10, 4);

    dynamic dynamic_ec = new ExampleClass();
    // The following line is not identified as an error by the
    // compiler, but it causes a run-time exception.
    dynamic_ec.exampleMethod1(10, 4);

    // The following calls also do not cause compiler errors, whether
    // appropriate methods exist or not.
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

이 예에서 컴파일러의 역할은 각 문이 dynamic 개체 또는 식에 수행할 작업에 대한 정보를 함께 패키지하는 것입니다. 런타임은 저장된 정보를 검사하며 유효하지 않은 문은 런타임 예외를 발생시킵니다.

대부분의 동적 작업은 결과 그 자체가 dynamic입니다. 다음 예제에서 testSum이 사용된 곳에 마우스 포인터를 올려두면 IntelliSense에서 (지역 변수) dynamic testSum 형식을 표시합니다.

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

결과가 dynamic이 아닌 작업은 다음과 같습니다.

  • dynamic에서 다른 형식으로의 전환.
  • dynamic 형식의 인수를 포함하는 생성자 호출.

예를 들어 다음 선언에서 testInstance의 형식은 dynamic이 아니라 ExampleClass입니다.

var testInstance = new ExampleClass(d);

변환

동적 개체와 다른 형식 간에 손쉽게 변환할 수 있습니다. 변환을 통해 개발자는 동적 동작과 비동적 동작 사이를 전환할 수 있습니다.

다음 예에 표시된 것처럼 any를 암시적으로 dynamic으로 변환할 수 있습니다.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

반대로, dynamic 형식의 식에 암시적 변환을 동적으로 적용할 수 있습니다.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

동적 형식의 인수로 오버로드 확인

메서드 호출 내 하나 이상의 인수에 dynamic 형식이 있거나 메서드 호출의 수신자가 dynamic 형식인 경우 오버로드 확인은 컴파일 시간이 아니라 런타임에 발생합니다. 다음 예에서 액세스 가능한 유일한 exampleMethod2 메서드가 문자열 인수를 사용하는 경우 d1을 인수로 보내면 컴파일러 오류가 발생하지 않지만 런타임 예외가 발생합니다. d1의 런타임 형식은 int인데 exampleMethod2에는 문자열이 필요하므로 오버로드 확인이 런타임에 실패합니다.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);

동적 언어 런타임

DLR(동적 언어 런타임)은 C#에서 dynamic 형식을 지원하는 인프라와 IronPython 및 IronRuby와 같은 동적 프로그래밍 언어의 구현도 제공합니다. DLR에 대한 자세한 내용은 동적 언어 런타임 개요를 참조하세요.

COM interop

많은 COM 메서드는 형식을 object로 지정하여 인수 형식 및 반환 형식의 변환을 허용합니다. COM interop에서는 C#의 강력한 형식의 변수와 조화를 이루기 위해 값을 명시적으로 캐스팅해야 합니다. EmbedInteropTypes(C# 컴파일러 옵션) 옵션을 사용하여 컴파일하는 경우 dynamic 형식을 도입하면 COM 서명에서 object의 발생을 마치 dynamic 형식인 것처럼 취급하여 캐스팅을 상당 부분 피할 수 있습니다. COM 개체와 함께 dynamic 형식을 사용하는 방법에 대한 자세한 내용은 C# 기능을 사용하여 Office 상호 운용성 개체에 액세스하는 방법 문서를 참조하세요.

제목 설명
dynamic dynamic 키워드의 사용법을 설명합니다.
동적 언어 런타임 개요 동적 언어에 대한 서비스 집합을 CLR(공용 언어 런타임)에 추가하는 런타임 환경인 DLR 개요를 제공합니다.
연습: 동적 개체 만들기 및 사용 사용자 지정 동적 개체를 만들고 IronPython 라이브러리에 액세스하는 프로젝트를 만드는 데 필요한 단계별 지침을 제공합니다.