C# 编译器如何检测 COM 类型? [英] How does the C# compiler detect COM types?
问题描述
我已将结果写成 博文.
<小时>C# 编译器有点神奇地处理 COM 类型.比如这个语句看起来很正常...
Word.Application app = new Word.Application();
... 直到您意识到 Application
是一个接口.在接口上调用构造函数?哎呀!这实际上被转换为对 Type.GetTypeFromCLSID()
和另一个Activator.CreateInstance
.
另外,在C#4中,你可以对ref
参数使用非ref参数,编译器只是添加了一个局部变量来通过引用传递,丢弃结果:
//FileName 参数*真的*是一个引用参数app.ActiveDocument.SaveAs(文件名:test.doc");
(是的,缺少一堆参数.可选参数不是很好吗?:)
我正在尝试调查编译器的行为,但我没有伪造第一部分.我可以毫无问题地完成第二部分:
使用系统;使用 System.Runtime.InteropServices;使用 System.Runtime.CompilerServices;[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]公共接口 Dummy{void Foo(ref int x);}课堂测试{静态无效主(){虚拟虚拟 = 空;dummy.Foo(10);}}
我希望能够写:
Dummy dummy = new Dummy();
虽然.显然它会在执行时爆炸,但没关系.我只是在试验.
编译器为链接的 COM PIA(CompilerGenerated
和 TypeIdentifier
)添加的其他属性似乎不起作用……有什么神奇之处?
我绝不是这方面的专家,但我最近偶然发现了我认为您想要的东西:CoClass 属性类.
[System.Runtime.InteropServices.CoClass(typeof(Test))]公共接口 Dummy { }
<块引用>
一个coclass提供混凝土一个或多个的实现接口.在 COM 中,这种具体的实现可以写成任何支持 COM 的编程语言组件开发,例如德尔福,C++、Visual Basic 等
参见 我对有关 Microsoft Speech API 的类似问题的回答,您可以在其中实例化"接口 SpVoice
(但实际上,您正在实例化 SPVoiceClass
>).
[CoClass(typeof(SpVoiceClass))]公共接口 SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }
EDIT: I've written the results up as a blog post.
The C# compiler treats COM types somewhat magically. For instance, this statement looks normal...
Word.Application app = new Word.Application();
... until you realise that Application
is an interface. Calling a constructor on an interface? Yoiks! This actually gets translated into a call to Type.GetTypeFromCLSID()
and another to Activator.CreateInstance
.
Additionally, in C# 4, you can use non-ref arguments for ref
parameters, and the compiler just adds a local variable to pass by reference, discarding the results:
// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");
(Yeah, there are a bunch of arguments missing. Aren't optional parameters nice? :)
I'm trying to investigate the compiler behaviour, and I'm failing to fake the first part. I can do the second part with no problem:
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);
}
}
I'd like to be able to write:
Dummy dummy = new Dummy();
though. Obviously it'll go bang at execution time, but that's okay. I'm just experimenting.
The other attributes added by the compiler for linked COM PIAs (CompilerGenerated
and TypeIdentifier
) don't seem to do the trick... what's the magic sauce?
By no means am I an expert in this, but I stumbled recently on what I think you want: the CoClass attribute class.
[System.Runtime.InteropServices.CoClass(typeof(Test))]
public interface Dummy { }
A coclass supplies concrete implementation(s) of one or more interfaces. In COM, such concrete implementations can be written in any programming language that supports COM component development, e.g. Delphi, C++, Visual Basic, etc.
See my answer to a similar question about the Microsoft Speech API, where you're able to "instantiate" the interface SpVoice
(but really, you're instantiating SPVoiceClass
).
[CoClass(typeof(SpVoiceClass))]
public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }
这篇关于C# 编译器如何检测 COM 类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!