Jak wywołać metodę prywatnych interfejsów COM zdefiniowanych w klasie bazowej?

Jak mogę wywołać metodę prywatnego interfejsu COM, zdefiniowaną w klasie bazowej, z klasy pochodnej?

Na przykład tutaj jest interfejs COM,IComInterface (IDL):

[
    uuid(9AD16CCE-7588-486C-BC56-F3161FF92EF2),
    oleautomation
]
interface IComInterface: IUnknown
{
    HRESULT ComMethod([in] IUnknown* arg);
}

Oto klasa C #BaseClass zOldLibrary montaż, który realizujeIComInterface tak (zauważ, że interfejs jest zadeklarowany jako prywatny):

// Assembly "OldLibrary"
public static class OldLibrary
{
    [ComImport(), Guid("9AD16CCE-7588-486C-BC56-F3161FF92EF2")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IComInterface
    {
        void ComMethod([In, MarshalAs(UnmanagedType.Interface)] object arg);
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class BaseClass : IComInterface
    {
        void IComInterface.ComMethod(object arg)
        {
            Console.WriteLine("BaseClass.IComInterface.ComMethod");
        }
    }
}

Wreszcie, mamy ulepszoną wersję,ImprovedClass, z którego pochodziBaseClass, ale deklaruje i implementuje własną wersjęIComInterface, ponieważ bazaOldLibrary.IComInterface jest niedostępny:

// Assembly "NewLibrary"
public static class NewLibrary
{
    [ComImport(), Guid("9AD16CCE-7588-486C-BC56-F3161FF92EF2")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IComInterface
    {
        void ComMethod([In, MarshalAs(UnmanagedType.Interface)] object arg);
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class ImprovedClass : 
        OldLibrary.BaseClass, 
        IComInterface, 
        ICustomQueryInterface
    {
        // IComInterface
        void IComInterface.ComMethod(object arg)
        {
            Console.WriteLine("ImprovedClass.IComInterface.ComMethod");
            // How do I call base.ComMethod here, 
            // otherwise than via reflection?
        }

        // ICustomQueryInterface
        public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
        {
            if (iid == typeof(IComInterface).GUID)
            {
                ppv = Marshal.GetComInterfaceForObject(this, typeof(IComInterface), CustomQueryInterfaceMode.Ignore);
                return CustomQueryInterfaceResult.Handled;
            }
            ppv = IntPtr.Zero;
            return CustomQueryInterfaceResult.NotHandled;
        }   

    }
}

Jak zadzwonić?BaseClass.ComMethod zImprovedClass.ComMethod bez refleksji?
Mogę użyć refleksji, ale w prawdziwym przypadku użyciaIComInterface to złożony interfejs OLE z wieloma członkami złożonych podpisów.

Myślałem tak, ponieważ obojeBaseClass.IComInterface iImprovedClass.IComInterface są zarówno interfejsami COM z tym samym identyfikatorem GUID, jak i identycznymi sygnaturami metodRównoważność typu COM w .NET 4.0+, więc musi istnieć sposób na zrobienie tego, czego oczekuję, bez refleksji.

Innym wymogiem jest toImprovedClass musi pochodzić odBaseClass, ponieważ kod klienta C # oczekuje wystąpieniaBaseClass, które przekazuje do kodu klienta COM. Tak więc, powstrzymywanieBaseClass wewnątrzImprovedClass nie jest opcją.

[EDITED] Scenariusz z życia codziennego, z którego wynikaWebBrowser iWebBrowserSite jest opisanytutaj.

questionAnswers(4)

yourAnswerToTheQuestion