오늘은 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() 메소드가 선언된 곳과 사용되고 있는 곳 코드를 찾아 수정해야 합니다.
인터페이스를 사용했다면 비쥬얼 스튜디오를 이용해서 자동으로 단번에 찾을 수 있는데 말이지요!