CoClassAttribute의 마술

CoClassAttribute는 인터페이스에 특별한 능력을 부여한다. 이름 그대로 특정 인터페이스와 단짝이 되는 형식을 지정한다는 뜻이다. 원래는 COM 상호 운용성을 위하여 추가된 기능이지만 이 CoClassAttribute의 능력으로 일어나는 재미있는 현상을 살펴보기로 한다.

CoClassAttribute는 단독으로 사용되지 않으며 GuidAttribute와 ComImportAttribute와 함께 쓰인다. 이 세 Attribute를 함께 조합하여 COM에서 가져온 CoClass가 설정된 인터페이스임을 뜻하는 것이 원래의 의미이지만 COM에서 가지고 온것이 아니어도 가능한 조합이다.

using System;
using System.Runtime.InteropServices;

[ComImport]
[CoClass(typeof(Test))]
[Guid(“DE1305DB-7814-4e94-9593-AC76DD58C24F”)]
public interface ITest
{
  int Add(int a, int b);
  int Sub(int a, int b);
  long Mul(int a, int b);
  double Div(int a, int b);
  int Mod(int a, int b);
}

public class Test : ITest
{
  int Add(int a, int b) { return a + b; }
  int Sub(int a, int b) { return a – b; }
  long Mul(int a, int b) { return (long)(a * b); }
  double Div(int a, int b) { return (double)(a / b); }
  int Mod(int a, int b) { return a % b; }
}


여기서 우리는 Test 클래스의 인스턴스를 생성하는 것이 당연하다고 생각되지만 ITest의 생성자를 호출해볼까 한다. 불가능한 일일까?

public class Test
{
  public static void Main()
  {
     ITest oTest = new ITest();
     Console.WriteLine(oTest.ToString());
  }
}

위와 같은 코드를 호출하였을 때 무엇이 나올까? 그렇다. CoClassAttribute가 제대로 동작해주었기 때문에 ITest 인터페이스로 할당을 하도록 했지만 실질적으로는 Test 클래스가 할당된 것이다. 그러나 CoClassAttribute로 지정된 형식이 인스턴스 생성을 원하는 코드의 입장에서 보호된 형식인 경우 생성자 호출을 할 수 없다.

댓글 남기기