До сих пор я всегда украшал свои классы.NET, которые я хочу использовать от VB6 с [AutoDual]
атрибут. Точка должна была получить Intellisense на объектах.NET в среде VB6. Однако на днях я погуглил AutoDual, и первый ответ, 'Не Используют AutoDual'.
Я искал когерентное объяснение того, почему я не должен использовать его, но не мог найти его.
Кто-то может здесь объяснить это?
Я думаю, это подводит итог:
Типы, использующие двойной интерфейс, позволяют клиентам связываться с определенным макетом интерфейса . Любые изменения в будущей версии макета типа или любых базовых типов нарушат работу клиентов COM , которые привязываются к интерфейсу. По умолчанию , если атрибут ClassInterfaceAttribute не указан, используется интерфейс только для отправки .
http://msdn.microsoft.com/en-us/library/ms182205.aspx
Это увеличивает вероятность того, что изменение чего-либо в этом классе с помощью атрибута auto dual приведет к поломке чужого кода при изменении класса . Если дает потребителю возможность делать что-то, что вполне может вызвать у него проблемы в будущем.
Следующая опция - ClassInterfaceType.AutoDual. Это быстрый и грязный способ получить поддержку раннего связывания (и сделать так, чтобы методы отображались в VB6 IntelliSense). Но также легко нарушить совместимость, изменив порядок методов или добавив новые перегрузки. Избегайте использования AutoDual.
http://www.dotnetinterop.com/faq/?q=ClassInterface
Наконец-то я нашел ссылку, которая рассказывает о том, что происходит с AutoDual и как она работает:
Предупреждение против AutoDual - это не факт, что использование двойных интерфейсов - это плохо, а {{ 1}} тот факт, что он автоматически генерирует для вас COM-интерфейс . Это плохо. Каждый раз, когда COM-интерфейс необходимо регенерировать, вы будете получать новый GUID и потенциально новых участников. Если GUID изменится, вы получите совершенно новый интерфейс / класс в том, что касается COM .Для раннего связывания вам придется перестраивать клиентов каждый раз, когда интерфейс создавался повторно. Предпочтительный подход заключается в явном определении интерфейса COM-класса с помощью GUID . Тогда все клиенты раннего связывания смогут использовать определенный интерфейс и не беспокоиться о том, что он изменится на них во время разработки. Вот почему рекомендуется использовать параметр "Нет", чтобы указать CLR не создавать его автоматически для . Вы по-прежнему можете реализовать двойной интерфейс , если он вам нужен.
Я нашел надежный способ предоставить Intellisense для объектов .NET в VB6, не нарушая при этом интерфейс. Ключ состоит в том, чтобы пометить каждый общедоступный метод / свойство в интерфейсе с помощью DispatchID. Затем класс должен наследовать от этого интерфейса - как показано ниже.
[Guid("BE5E0B60-F855-478E-9BE2-AA9FD945F177")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICriteria
{
[DispId(1)]
int ID { get; set; }
[DispId(2)]
string RateCardName { get; set; }
[DispId(3)]
string ElectionType { get; set; }
}
[Guid("3023F3F0-204C-411F-86CB-E6730B5F186B")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyNameSpace.Criteria")]
public class Criteria : ICriteria
{
public int ID { get; set; }
public string RateCardName { get; set; }
public string ElectionType { get; set; }
}
Идентификатор отправки дает вам возможность перемещать элементы в классе, плюс теперь вы можете добавлять новые элементы в класс и не нарушать двоичную совместимость.