编辑: 我已经将结果写为博客文章。
C#编译器以某种魔术方式对待COM类型。例如,此语句看起来很正常…
Word.Application app = new Word.Application();
…直到您意识到这Application是一个界面。在接口上调用构造函数?ik!实际上,这会转化为的调用Type.GetTypeFromCLSID(),另一个是的调用Activator.CreateInstance。
Application
Type.GetTypeFromCLSID()
Activator.CreateInstance
此外,在C#4中,您可以对ref参数使用非引用参数,并且编译器仅添加一个局部变量以通过引用传递,并丢弃结果:
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(CompilerGenerated和TypeIdentifier)添加的其他属性似乎并没有解决问题的方法……魔咒是什么?
CompilerGenerated
TypeIdentifier
我绝对不是这方面的专家,但是最近我偶然发现了我认为您想要的东西:CoClass属性类。
[System.Runtime.InteropServices.CoClass(typeof(Test))] public interface Dummy { }
协类提供一个或多个接口的具体实现。在COM中,可以使用支持COM组件开发的任何编程语言(例如Delphi,C ++,Visual Basic等)编写此类具体实现。
请参阅我对有关Microsoft Speech API的类似问题的回答,您可以在其中“实例化”该接口SpVoice(但实际上,您正在实例化SPVoiceClass)。
SpVoice
SPVoiceClass
[CoClass(typeof(SpVoiceClass))] public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }