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?