为什么为 属性 类型生成的包装器选择此接口?

Why is the generated wrapper for property type selecting this interface?

当我要求 Visual Studio 为我的 COM 组件生成运行时可调用包装器时,它正在选择一个奇怪的类型来包装某个接口 属性。

这是组件 A 的汇总类型库:

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: prodist.sts.dll

[
  uuid(DD00B52D-D8F9-4D5C-ADBD-4E05A68A48CB),
  version(5.4),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 134218331),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1423075247),
  custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 8.00.0603 at Wed Feb 04 16:40:46 2015
"),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "prodist.sts")

]
library prodist_sts
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");
    // TLib :  : {F11596CA-03EE-4756-B502-0327800ED8B4}
    importlib("prodist.logging.dll");

    // Forward declare all types defined in this typelib
    interface ISts;
    interface IStsSession;
    interface IStream;
    interface ISequentialStream;

    [
      uuid(EE263AAA-67D4-48DD-9DF5-69ED8CF0D0C9)
    ]
    coclass Sts {
        [default] interface ISts;
    };

    [
      odl,
      uuid(8D841E5C-F25B-4C12-B03A-70A899B3A32E),
      dual,
      nonextensible,
      oleautomation
    ]
    interface ISts : IDispatch {
        [id(0x000003e9), propget]
        HRESULT Logging([out, retval] IProdistLoggingHierarchy** value);
        [id(0x000003e9), propput]
        HRESULT Logging(IProdistLoggingHierarchy* value);
        [id(0x000003e8)]
        HRESULT CreateSession([out, retval] IStsSession** result);
    };

    // ...
}

这是组件 B 的类型库:

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: prodist.sts.rsfn.dll

[
  uuid(C8FBF2B0-9218-4B0D-9509-C394D65F0566),
  version(5.4),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 134218331),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1423076189),
  custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 8.00.0603 at Wed Feb 04 16:56:28 2015
"),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "prodist.sts.rsfn")

]
library prodist_sts_rsfn
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");
    // TLib :  : {DD00B52D-D8F9-4D5C-ADBD-4E05A68A48CB}
    importlib("prodist.sts.dll");
    // TLib :  : {F11596CA-03EE-4756-B502-0327800ED8B4}
    importlib("prodist.logging.dll");

    // Forward declare all types defined in this typelib
    interface IApiMensageria2;
    interface IApiMensageria;
    interface IApiMensageriaContext;
    interface IStsRsfn;
    interface IStsRsfnContext;
    interface IStsRsfnSession;

    [
      uuid(914E8C54-E0F0-4322-8803-8E9EEEE03A01)
    ]
    coclass StsRsfn {
        [default] interface IStsRsfn;
    };

    [
      odl,
      uuid(13385FC6-2618-4830-A3A9-703398AA5A0B),
      dual,
      nonextensible,
      oleautomation
    ]
    interface IStsRsfn : IDispatch {
        [id(0x000003e9), propget]
        HRESULT Logging([out, retval] IProdistLoggingHierarchy** value);
        [id(0x000003e9), propput]
        HRESULT Logging(IProdistLoggingHierarchy* value);
        [id(0x000003e8), propget]
        HRESULT Sts([out, retval] ISts** value);
        [id(0x000003e8), propput]
        HRESULT Sts(ISts* value);
        [id(0x000003f1)]
        HRESULT CreateContext([out, retval] IStsRsfnContext** result);
        [id(0x000003f2)]
        HRESULT CreateSession([out, retval] IStsRsfnSession** result);
    };

    // ...
}

这是 Visual Studio 为组件 A 生成的运行时可调用包装器:

[ClassInterface(0)]
[Guid("EE263AAA-67D4-48DD-9DF5-69ED8CF0D0C9")]
[TypeLibType(2)]
public class StsClass : ISts, Sts
{
    public StsClass();

    [DispId(1001)]
    public virtual IProdistLoggingHierarchy Logging { get; set; }

    [DispId(1000)]
    public virtual IStsSession CreateSession();
}

[CoClass(typeof(StsClass))]
[Guid("8D841E5C-F25B-4C12-B03A-70A899B3A32E")]
public interface Sts : ISts
{
}

[Guid("8D841E5C-F25B-4C12-B03A-70A899B3A32E")]
[TypeLibType(4288)]
public interface ISts
{
    [DispId(1001)]
    IProdistLoggingHierarchy Logging { get; set; }

    [DispId(1000)]
    IStsSession CreateSession();
}   

这是 Visual Studio 为组件 B 生成的运行时可调用包装器:

[ClassInterface(0)]
[Guid("914E8C54-E0F0-4322-8803-8E9EEEE03A01")]
[TypeLibType(2)]
public class StsRsfnClass : IStsRsfn, StsRsfn
{
    public StsRsfnClass();

    [DispId(1001)]
    public virtual IProdistLoggingHierarchy Logging { get; set; }
    [DispId(1000)]
    public virtual Sts Sts { get; set; }

    [DispId(1009)]
    public virtual IStsRsfnContext CreateContext();
    [DispId(1010)]
    public virtual IStsRsfnSession CreateSession();
}

[CoClass(typeof(StsRsfnClass))]
[Guid("13385FC6-2618-4830-A3A9-703398AA5A0B")]
public interface StsRsfn : IStsRsfn
{
}

[Guid("13385FC6-2618-4830-A3A9-703398AA5A0B")]
[TypeLibType(4288)]
public interface IStsRsfn
{
    [DispId(1001)]
    IProdistLoggingHierarchy Logging { get; set; }
    [DispId(1000)]
    Sts Sts { get; set; }

    [DispId(1009)]
    IStsRsfnContext CreateContext();
    [DispId(1010)]
    IStsRsfnSession CreateSession();
}

为什么Visual Studio选择Sts接口而不是ISts接口来包裹IStsRsfn.Sts属性?

因为接口 IStsSts 组件类的默认接口,没有其他组件类实现它。

在这种情况下,我猜导入器选择了它曾经认为是某些 coclass 的默认接口并且没有其他实现的接口。