C#编译器如何检测COM类型? [英] How does the C# compiler detect COM types?
问题描述
EDIT:我已将结果写成 blog post 。
编译器在某种程度上处理COM类型。例如,此语句看起来正常...
Word.Application app = new Word.Application
...直到你意识到 Application
是一个接口。调用接口上的构造函数? Yoiks!这实际上转换为调用 Type.GetTypeFromCLSID()
和另一个 Activator.CreateInstance
。
此外,在C#4中, ref
参数的非引用参数,编译器只是添加一个局部变量作为引用传递,舍弃结果:
// FileName参数是* really * a ref参数
app.ActiveDocument.SaveAs(FileName:test.doc);
(是的,有一堆参数丢失。 / p>
我试图调查编译器的行为,我没有假的第一部分。我可以做第二部分没有问题:
使用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);
}
}
我希望能够写: / p>
Dummy dummy = new Dummy();
显然,它会在执行时间爆炸,但是没关系。
编译器为链接COM PIA添加的其他属性( CompilerGenerated
和<$
我不是我的专家,但我最近偶然发现了我想要的: CoClass 属性类。
[System.Runtime .InteropServices.CoClass(typeof(Test))]
public interface Dummy {}
coclass提供一个或多个
接口的具体
实现。在COM中,这种具体的
实现可以用支持COM
组件开发的任何
编程语言编写。 Delphi,
C ++,Visual Basic等。
查看我对类似问题的回答关于Microsoft Speech API ,其中你可以实例化接口 SpVoice
(但实际上,你是实例化 SPVoiceClass
)。 p>
[CoClass(typeof(SpVoiceClass))]
public interface 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屋!