See the question and my original answer on StackOverflow

You can use the ICustomQueryInterface interface. It will allow you to return IUnknown interfaces "manually" and still benefit from the IDispatch implementation provided by .NET. So, for example, if you have an unmanaged IUnknown interface "IMyUnknown" that contains one method (named "MyUnknownMethod" in the sample), you can declare your .NET class like this:

[ComVisible(true)]
public class Class1 : ICustomQueryInterface, IMyUnknown
{
    CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv)
    {
        if (iid == typeof(IMyUnknown).GUID)
        {
            ppv = Marshal.GetComInterfaceForObject(this, typeof(IMyUnknown), CustomQueryInterfaceMode.Ignore);
            return CustomQueryInterfaceResult.Handled;
        }

        ppv = IntPtr.Zero;
        return CustomQueryInterfaceResult.NotHandled;
    }

    // an automatic IDispatch method
    public void MyDispatchMethod()
    {
       ...
    }

    // the IMyUnknown method
    // note you can declare that method with a private implementation
    public void MyUnknownMethod()
    {
       ...
    }
}