Почему открытые типы должны быть запечатаны для компонентов WinMD/WinRT?

Компилятор VS не позволяет создавать запечатанные открытые типы для библиотеки типов WINMD.

Почему введено это ограничение? (Я знаю о преимуществах запечатанных типов, мой вопрос касается компонентов Win RT).


person Tilak    schedule 08.05.2012    source источник
comment
Ваш заголовок, кажется, не согласен с вопросом? (должен быть запечатан, а не запечатан)   -  person Hans Kesting    schedule 08.05.2012


Ответы (2)


Это архитектурное ограничение, налагаемое COM. Которые лежат в основе любого типа WinRT, они являются производными от IUnknown и IInspectable. Проблема с COM заключается в том, что он поддерживает только наследование интерфейса, но не наследование реализации. Что было серьезной целью дизайна COM, наследование реализации слишком чревато деталями реализации, включая печально известную проблему алмаза.

Есть способ заставить наследование работать делегированием, каждый метод в производном классе явно вызывает соответствующий метод базового интерфейса, но это очень сложно сделать самостоятельно. Но в остальном способ, которым классы Windows.UI.Xaml реализуют наследование.

person Hans Passant    schedule 08.05.2012
comment
Это отвечает на вопрос. отдельное спасибо за упоминание проблемы с бриллиантами - person Tilak; 08.05.2012
comment
Это не совсем точно, можно реализовать незапечатанные классы winrt, но их нельзя использовать из JavaScript, и они требуют использования низкоуровневого (IDL) опыта разработки, который может быть довольно сложным для Visual Studio. Кроме того, все производные классы (запечатанные или незапечатанные) ДОЛЖНЫ в конечном итоге происходить от классов в пространстве имен Windows. - person ReinstateMonica Larry Osterman; 09.05.2012
comment
Можете ли вы указать на любую подтверждающую документацию. Я хотел бы увидеть, как это можно сделать. В моем случае мне нужно все это в VS, но стоило бы знать, как обстоят дела в фоновом режиме. - person Tilak; 09.05.2012

Я считаю, что причина в том, что открытые типы должны использоваться на всех языках (C#, C++, JavaScript и, возможно, в будущем).

Итак, если у вас есть класс, то одним из способов использования класса является его переопределение в новый класс. Я мог бы переопределить класс, который делается на другом языке. Но это проблема. Как вы хотите переопределить базовый класс, созданный на C#, классом-наследником, созданным на C++? Это никогда не сработает, потому что оба они имеют совершенно разные и несовместимые реализации ООП.

Принудительно запечатывая открытые классы, вы устраняете эту проблему и гарантируете, что люди не попытаются сделать что-то подобное.

Я уверен, что есть гораздо более фундаментальные вещи, чем это, но это первое, что пришло мне в голову.

person Euphoric    schedule 08.05.2012