четверг, 15 ноября 2012 г.

Создание экземпляра интерфейса.

Немного шокирует, что эта штука будет работать :)
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // ухты !!!
            IFoo i = new IFoo("Hello");
            i.Print();

            Console.WriteLine(i.GetType());

            Console.ReadLine();
        }

        [Guid("40DCF1C3-C39D-4BB0-B967-1391C56E2852")]
        [CoClass(typeof(Foo))]
        [ComImport]
        interface IFoo
        {
            void Print();
        }

        class Foo : IFoo
        {
            private string _message;

            public Foo(string message)
            {
                _message = message;
            }

            public void Print()
            {
                Console.WriteLine(_message);
            }
        }
    }
}

К интерфейсу (во время компиляции!) "подвязывается" экземпляр дефолтового класса (что-то типа Activator.CreateInstance(Type.GetTypeFromClsid(GUID OF COCLASSTYPE)), и дальше все работает так, будто бы мы явно создавали экземпляр конкретного класса. Вникать историю развития COM особого желания нету, но пример забавный. К сожалению, трудно представить реальное применение этой фичи.