一尘不染

C#编译器如何检测COM类型?

c#

编辑: 我已经将结果写为博客文章


C#编译器以某种魔术方式对待COM类型。例如,此语句看起来很正常…

Word.Application app = new Word.Application();

…直到您意识到这Application是一个界面。在接口上调用构造函数?ik!实际上,这会转化为的调用Type.GetTypeFromCLSID(),另一个是的调用Activator.CreateInstance

此外,在C#4中,您可以对ref参数使用非引用参数,并且编译器仅添加一个局部变量以通过引用传递,并丢弃结果:

// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");

(是的,缺少很多参数。可选参数不是很好吗?:)

我正在尝试调查编译器的行为,但未能伪造第一部分。我可以毫无问题地完成第二部分:

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]
public interface Dummy
{
    void Foo(ref int x);
}

class Test
{
    static void Main()
    {
        Dummy dummy = null;
        dummy.Foo(10);
    }
}

我希望能够写:

Dummy dummy = new Dummy();

虽然。显然它会在执行时爆炸,但这没关系。我只是在尝试。

编译器为链接的COM
PIA(CompilerGeneratedTypeIdentifier)添加的其他属性似乎并没有解决问题的方法……魔咒是什么?


阅读 353

收藏
2020-05-19

共1个答案

一尘不染

我绝对不是这方面的专家,但是最近我偶然发现了我认为您想要的东西:CoClass属性类。

[System.Runtime.InteropServices.CoClass(typeof(Test))]
public interface Dummy { }

协类提供一个或多个接口的具体实现。在COM中,可以使用支持COM组件开发的任何编程语言(例如Delphi,C ++,Visual
Basic等)编写此类具体实现。

请参阅我对有关Microsoft Speech
API的类似问题的回答
,您可以在其中“实例化”该接口SpVoice(但实际上,您正在实例化SPVoiceClass)。

[CoClass(typeof(SpVoiceClass))]
public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }
2020-05-19