EDYCJA: Zapisałem wyniki jako wpis na blogu .
Kompilator C # traktuje typy COM nieco magicznie. Na przykład to stwierdzenie wygląda normalnie ...
Word.Application app = new Word.Application();
... dopóki nie zdasz sobie sprawy, że Application
to interfejs. Wywołanie konstruktora w interfejsie? Yoiks! To faktycznie jest tłumaczone na wywołanie do, Type.GetTypeFromCLSID()
a drugie na Activator.CreateInstance
.
Dodatkowo w C # 4 można użyć argumentów innych niż ref dla ref
parametrów, a kompilator po prostu dodaje zmienną lokalną do przekazania przez odwołanie, odrzucając wyniki:
// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");
(Tak, brakuje wielu argumentów. Czy parametry opcjonalne nie są ładne? :)
Próbuję zbadać zachowanie kompilatora i nie udaje mi się sfałszować pierwszej części. Drugą część mogę zrobić bez problemu:
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);
}
}
Chciałbym móc napisać:
Dummy dummy = new Dummy();
chociaż. Oczywiście wybuchnie w czasie egzekucji, ale to w porządku. Po prostu eksperymentuję.
Inne atrybuty dodane przez kompilator do połączonych PIA COM ( CompilerGenerated
i TypeIdentifier
) nie wydają się działać ... co to za magiczny sos?
dynamic
... jesteśmy zbyt przyzwyczajeni do statycznego / silnego pisania, aby zobaczyć, dlaczego miałoby to znaczenie poza COM.