From 8b4323d1fea923b76f578715f5127a14bcec146a Mon Sep 17 00:00:00 2001 From: MarkFern <49532200+MarkFern@users.noreply.github.com> Date: Fri, 12 Apr 2019 15:00:47 +0100 Subject: [PATCH] DispIds compile-time caching is bad? Proposed change(s) ********************* 1) Last sentence of "Restrict using the dual interface option for the class interface." section should be: "... Such a description encourages late-bound clients to cache DispIds at compile time. ..." instead. Justifications for suggestion(s) ******************************** 1. Caching at compile time seems to be an issue because run time can take place a long time (maybe even years) after compile time, at which time, the DispId values may have changed. Caching at run time doesn't seem likely to be much of an issue so long as the cache is refreshed / created / re-created every time the associated type is changed (which seems should be the case in the vast majority of situations). The tone of the writing in question, appears likely to indicate that the caching is undesirable. Because of this, and what I've written earlier in this paragraph, it seems likely that the author meant to refer to compile-time caching & not run-time caching. 2. The original author meaning compile-time caching would make sense because the exported type library, available at compile time, contains the DispIds that are to be cached. See 'https://docs.microsoft.com/en-us/windows/desktop/midl/id' to help understand that the DispIds are available in the type library (which is available at compile time). 3. In the 'Avoid caching dispatch identifiers (DispIds)' section on the page, is written: "...To avoid breaking late-bound COM clients when using the class interface, apply the ClassInterfaceAttribute with the ClassInterfaceType.AutoDispatch value. This value implements a dispatch-only class interface, but omits the interface description from the type library. Without an interface description, clients are unable to cache DispIds at compile time. ..." This reference to caching DispIds at compile time, is quite likely what was meant to be referred to in the text I have suggested needs changing. In this reference above, inability to do such caching is suggested as being good in order to prevent '...breaking late-bound COM clients ...' My suggested change makes sense in connection with this, as with my suggestion applied, this 'goodness' assertion is re-iterated (although by inverting the language terms the second time). The second time, instead of saying not being able to do such caching is good, with the change, it is implied that being able to do such caching is bad. --- docs/framework/interop/com-callable-wrapper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework/interop/com-callable-wrapper.md b/docs/framework/interop/com-callable-wrapper.md index 63b70ba9846ea..91576be40b21c 100644 --- a/docs/framework/interop/com-callable-wrapper.md +++ b/docs/framework/interop/com-callable-wrapper.md @@ -177,7 +177,7 @@ To get the DispId of an interface member at run time, COM clients can call **IDi Dual interfaces enable early and late binding to interface members by COM clients. At design time and during testing, you might find it useful to set the class interface to dual. For a managed class (and its base classes) that will never be modified, this option is also acceptable. In all other cases, avoid setting the class interface to dual. -An automatically generated dual interface might be appropriate in rare cases; however, more often it creates version-related complexity. For example, COM clients using the class interface of a derived class can easily break with changes to the base class. When a third party provides the base class, the layout of the class interface is out of your control. Further, unlike a dispatch-only interface, a dual interface (**ClassInterfaceType.AutoDual**) provides a description of the class interface in the exported type library. Such a description encourages late-bound clients to cache DispIds at run time. +An automatically generated dual interface might be appropriate in rare cases; however, more often it creates version-related complexity. For example, COM clients using the class interface of a derived class can easily break with changes to the base class. When a third party provides the base class, the layout of the class interface is out of your control. Further, unlike a dispatch-only interface, a dual interface (**ClassInterfaceType.AutoDual**) provides a description of the class interface in the exported type library. Such a description encourages late-bound clients to cache DispIds at compile time. ### Ensure that all COM event notifications are late-bound.