2010-04-26 43 views
7

Cho đến bây giờ, tôi đã luôn trang trí các lớp .NET của mình mà tôi muốn sử dụng từ VB6 với thuộc tính [AutoDual]. Vấn đề là để có được Intellisense trên các đối tượng .NET trong môi trường VB6. Tuy nhiên, ngày hôm kia tôi googled AutoDual và câu trả lời đầu tiên là 'Không sử dụng AutoDual'.Tại sao tôi không nên sử dụng Tự động?

Tôi đã tìm kiếm giải thích mạch lạc về lý do tại sao tôi không nên sử dụng nó, nhưng không thể tìm thấy nó.

Ai đó ở đây có thể giải thích nó không?

Trả lời

8

Tôi nghĩ rằng đây tóm nó lên:

loại sử dụng một giao diện kép cho phép khách hàng liên kết với một cách bố trí giao diện cụ thể. Mọi thay đổi trong phiên bản tương lai đối với bố cục của loại hoặc bất kỳ loại cơ sở nào sẽ phá vỡ COM khách hàng liên kết với giao diện. Theo mặc định là , nếu thuộc tính Class2nter16A106 Thuộc tính ClassInterfaceAttribute là không được chỉ định, giao diện chỉ gửi đi được sử dụng.

http://msdn.microsoft.com/en-us/library/ms182205.aspx

Nó làm tăng khả năng rằng việc thay đổi một cái gì đó ở chỗ lớp với các thuộc tính tự động kép sẽ phá vỡ mã của người khác khi lớp được thay đổi. Nếu cung cấp cho người tiêu dùng khả năng làm điều gì đó mà có thể sẽ gây ra vấn đề cho họ trong tương lai.

Tùy chọn tiếp theo là ClassInterfaceType.AutoDual. Đây là cách nhanh chóng và bẩn để có được sự hỗ trợ ràng buộc sớm (và làm cho các phương thức hiển thị trong VB6 IntelliSense). Nhưng nó cũng dễ dàng phá vỡ khả năng tương thích, bằng cách thay đổi thứ tự các phương thức hoặc thêm các tình trạng quá tải mới. Tránh sử dụng Tự động.

http://www.dotnetinterop.com/faq/?q=ClassInterface

cuối cùng tôi đã tìm thấy các liên kết mà nói về những gì đang xảy ra với AutoDual và làm thế nào nó hoạt động:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7fa723e4-f884-41dd-9405-1f68afc72597

Cảnh báo chống lại AutoDual không phải là thực tế là giao diện kép là xấu nhưng thực tế là nó tự động tạo giao diện COMCOM cho bạn. Thật tệ. Mỗi lần giao diện COM phải là được tái tạo, bạn sẽ nhận được GUID mới và thành viên mới có khả năng. Nếu GUID thay đổi thì bạn sẽ có giao diện hoàn toàn mới cho đến khi COM là có liên quan. Đối với ràng buộc sớm, bạn muốn phải xây dựng lại khách hàng mỗi lần giao diện được tạo lại. Cách tiếp cận ưa thích là xác định giao diện lớp học COM một cách rõ ràng với một GUIDE . Sau đó tất cả các ràng buộc sớm khách hàng có thể sử dụng giao diện được xác định và không phải lo lắng về việc thay đổi trên chúng trong quá trình phát triển. Đó là lý do tại sao tùy chọn được đề nghị là Không để cho biết CLR không tự động tạo nó cho bạn. Bạn vẫn có thể triển khai giao diện kép mặc dù nếu bạn cần.

+0

Phần tôi không rõ ràng là: 'Bất kỳ thay đổi nào trong phiên bản tương lai đối với bố cục của loại hoặc bất kỳ loại cơ sở nào sẽ phá vỡ các máy khách COM '. Có nghĩa là nếu tôi thay đổi một thuộc tính từ int thành gấp đôi, client sẽ phá vỡ? Hay nó có nghĩa là nếu tôi đơn giản biên dịch lại phần .NET, máy khách VB6 sẽ không còn có thể sử dụng nó nữa? – AngryHacker

+0

Miễn là bạn không thay đổi giao diện, bạn nên ổn. http://www.dotnetinterop.com/faq/?q=ClassInterface – kemiller2002

+0

@Kevin, vì vậy chỉ cần biên dịch lại thư viện .NET của tôi sẽ không phá vỡ người tiêu dùng? Và 'thay đổi thứ tự các phương thức' thực sự có ý nghĩa gì? Có nghĩa là thay đổi thứ tự của các phương thức trong mã? Tôi vẫn không hiểu rõ tại sao chúng ta nên tránh AutoDual. Tôi nghĩ rằng điều này được hiểu rằng nếu bạn thay đổi giao diện, hơn người tiêu dùng sẽ không hoạt động. Nó luôn luôn được như vậy trong thế giới VB6. – AngryHacker

11

Tôi đã tìm được cách đáng tin cậy để cung cấp Intellisense cho các đối tượng .NET trong VB6, đồng thời không phá vỡ giao diện. Điều quan trọng là đánh dấu từng phương thức/thuộc tính công khai trong giao diện với DispatchID. Sau đó, lớp phải kế thừa từ giao diện này - theo cách bên dưới.

[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; } 
} 

ID công văn cung cấp cho bạn là khả năng di chuyển xung quanh các mục trong lớp, cộng với bây giờ bạn có thể thêm nội dung mới vào lớp và không phá vỡ tính tương thích nhị phân.

Các vấn đề liên quan