简体   繁体   中英

Is it possible to use late binding on a COM object inside a T4 template?

My T4 template instantiates an Excel COM object to read some cell values and create C# classes from them. I wrote the Excel reading logics in regular C# first, which works fine. A code snippet that I use in this test is:

Worksheet xlWorkSheet;
string cellContents = xlWorkSheet.Cells.Item[1, 1].Value;

Transplanting the test code into a T4 template does not work though. The following error is displayed:

Error 1: Compiling transformation: 'object' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

The only way for me to resolve this, is by adding some manual casting:

string cellContents = (xlWorkSheet.Cells.Item[1, 1] as Range).Value as string;

I was under the impression that T4 uses the "regular" C# compiler and as such, would be able to deal with dynamic binding like regular code can. But apparently, there are differences. In this case, I could resolve my issues because I was able to guess what type to cast to. In general, that is not the case though. Is there a way to make this late binding work in a T4 template?

Both T4 and C# can cope with dynamic binding using the 'dynamic' keyword. Neither can infer it without this keyword.

However, in the regular IDE, it's possible to set the flag 'Embed Interop Types" on an assembly reference. This feature copies the referenced interop types directly into the consuming assembly and also, on the fly, translates 'object' references to 'dynamic'.

Hence the example code in the question compiles in normal C# within the IDE as the 'Item' collection is converted to return a 'dynamic'.

T4 doesn't have an equivalent flag for its 'assembly' directive, so you have to declare your expressions as dynamic manually. For that to work, you have to include the following assembly directives to your template as well:

<#@ assembly name="System.Core" #>
<#@ assembly name="Microsoft.CSharp" #>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM