Post List

2018/01/26

C#__6.0 dynamic 형식

오늘은 dynamic형식 대해 알아보겠습니다.
Dynamic형식도 int, string처럼 하나의 데이터 형식입니다. 다만 형식 검사가 컴파일할 이루어지는 다른 형식과 달리 실행할 이루어진다는 점이 dynamic형식의 특징입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClass
{
    public void FuncA()
    { 
    }
}
static void Main(string[] args)
{
    MyClass myclass = new MyClass();
    myclass.FuncA();
    myclass.FuncB();
}
cs

코드가 있을 , 컴파일 애러가 납니다. 이유는 MyClass FuncB라는 메소드를 가지고있지 않기 때문이지요.
그럼 myclass dynamic형식으로 변경해서 다시 테스트해보겠습니다.

1
2
3
dynamic myclass = new MyClass();
myclass.FuncA();
myclass.FuncB();
cs

위와 같이 MyClass 타입을 dynamic으로 변경하니 컴파일 에러는 발생하지 않습니다. 처럼 dynamic 키워드를 이용해서 컴파일러의 방해 없이 실행파일을 만들어 있습니다. 컴파일러가 dynamic 키워드를 만나면 형식 검사를 실행할 하도록 미루기 때문이지요.


오리 타이핑
오리 타이핑은 객체 지향 프로그래밍과는 상당히 다른 각도에서 형식을 바라봅니다. 예를 들어 C#에서 어떤 형식이 오리라고 인정받으려면 형식의 조상 중에 오리가 있어야 하지요? 다음 코드를 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Duck
{
    public void Walk()
    {  Console.WriteLine("Duck.Walk"); }
    public void Swim()
    {  Console.WriteLine("Duck.Swim"); }
     public void Quack()
    {  Console.WriteLine("Duck.Quack"); }
}
class Mallard : Duck
}
cs

오리 타이핑에서 어떤 형식이 오리로 인정을 받으려면 오리처럼 걷고, 오리처럼 헤엄치고, 오리처럼 꽉꽉 거리기만 하면 됩니다.
형식이 어느 형식으로부터 상속받는지는 전혀 중요하지 않죠, 다음은 오리 타이핑에서 오리로 인정하는 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
class Robot
{
    public void Walk()
    { Console.WriteLine("Robot.Walk"); }
     public void Swim()
    { Console.WriteLine("Robot.Swim"); }
     public void Quack()
    { Console.WriteLine("Robot.Quack"); }
}
cs

오리 타이핑 관점에서 보면 코드에서 선언한 Duck 오리고, Robot 오리입니다. 오리처럼 걷고, 헤엄치고, 꽉꽉 거리지요.
하지만 C#컴파일러는 Duck이나 Mallard 오리로 인정해도 Robot 오리로 인정하지 않습니다. Duck 형식의 배열을 선언하고 여기에 Duck, Mallard, Robot 인스턴스를 요소로 넣어 초기화할 컴파일러는 형식 검사를 하면서 Robot 대해 Duck형식이 아니라고 에러메시지가 납니다.

1
Duck[] arr = new Duck[] { new Duck(), new Mallard(), new Robot() };
cs




이런 경우 dynamic형식을 통해 해결할 있습니다. Dynamic 형식이 형식 검사를 실행할 때로 미룬다는 점을 이용하는 겁니다.

1
2
3
4
5
6
7
8
dynamic[] arr = new dynamic[] { new Duck(), new Mallard(), new Robot() }; 
foreach(dynamic duck in arr)
{
    Console.WriteLine(duck.GetType());
    duck.Walk();
    duck.Swim();
    duck.Quack();
cs

오리 타이핑 사용법을 알았으니, 그럼 오리 타이핑은 사용하는 것일까요?

인터페이스를 설계하기 위해서는 추상화를 해야 하는데 추상화를 잘하려면 연습과 경험이 많이 필요합니다.
인터페이스를 잘못 설계했다가는 나중에 파생 클래스를 수정해야 일이 생기면 위로는 인터페이스를 수정하고, 아래로는 자신의 파생 클래스들, 옆으로는 형제 클래스들을 줄줄이 수정해야 하는 일이 생기지요.

오리 타이핑은 이런 문제를 만났을 유연하게 해결할 있도록 돕습니다. 상속 관계를 이용하지 않기 때문에 프로그램의 동작에 관여하는 부분만 손을 대면 되기때문이죠.

하지만, 오리 타이핑이 좋은점만 있는 것은 아닙니다. 우선 비쥬얼 스튜디오의 리팩토링 기능을 이용할 없습니다. 만약, Walk() 메소드의 이름을 Run()으로 고치고 싶어도 여러분이 직접 Walk() 메소드가 선언된 곳과 사용되고 있는 코드를 찾아 수정해야 합니다.
인터페이스를 사용했다면 비쥬얼 스튜디오를 이용해서 자동으로 단번에 찾을 있는데 말이지요!