Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以在T4模板内的COM对象上使用后期绑定?_C#_.net_C# 4.0_T4 - Fatal编程技术网

C# 是否可以在T4模板内的COM对象上使用后期绑定?

C# 是否可以在T4模板内的COM对象上使用后期绑定?,c#,.net,c#-4.0,t4,C#,.net,C# 4.0,T4,我的T4模板实例化一个Excel COM对象来读取一些单元格值并从中创建C#类。我首先用常规的C#编写了Excel读取逻辑,效果很好。我在本测试中使用的代码片段是: Worksheet xlWorkSheet; string cellContents = xlWorkSheet.Cells.Item[1, 1].Value; 不过,将测试代码移植到T4模板中并不起作用。将显示以下错误: 错误1:编译转换:“object”不包含“Value”的定义,并且找不到接受“object”类型的第一个参数

我的T4模板实例化一个Excel COM对象来读取一些单元格值并从中创建C#类。我首先用常规的C#编写了Excel读取逻辑,效果很好。我在本测试中使用的代码片段是:

Worksheet xlWorkSheet;
string cellContents = xlWorkSheet.Cells.Item[1, 1].Value;
不过,将测试代码移植到T4模板中并不起作用。将显示以下错误:

错误1:编译转换:“object”不包含“Value”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“Value”(是否缺少using指令或程序集引用?

解决这个问题的唯一方法是添加一些手动铸造:

string cellContents = (xlWorkSheet.Cells.Item[1, 1] as Range).Value as string;
我的印象是T4使用“常规”C#编译器,因此能够像常规代码一样处理动态绑定。但显然,两者之间存在差异。在这种情况下,我可以解决我的问题,因为我能够猜出要转换到哪种类型。但总的来说,情况并非如此。有没有办法在T4模板中实现这种后期绑定?

T4和C#都可以使用“dynamic”关键字处理动态绑定。没有这个关键字,任何人都无法推断

但是,在常规IDE中,可以在程序集引用上设置标志“嵌入互操作类型”。此功能将引用的互操作类型直接复制到使用程序集中,并且还可以动态地将“对象”引用转换为“动态”

因此,问题中的示例代码在IDE中以普通C#编译,因为“Item”集合被转换为返回“dynamic”

T4的“assembly”指令没有等效的标志,因此您必须手动将表达式声明为动态。要使其工作,您还必须在模板中包含以下
assembly
指令:

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

T4和C#都可以使用“dynamic”关键字处理动态绑定。没有此关键字,两者都无法推断

但是,在常规IDE中,可以在程序集引用上设置标志“嵌入互操作类型”。此功能将引用的互操作类型直接复制到使用程序集中,并且动态地将“对象”引用转换为“动态”

因此,问题中的示例代码在IDE中以普通C#编译,因为“Item”集合被转换为返回“dynamic”

T4的“assembly”指令没有等效的标志,因此您必须手动将表达式声明为动态的。为此,您还必须在模板中包含以下
assembly
指令:

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


您使用的是哪一版本的t4?不确定如何检查t4的版本,但我在Visual C#2010 Express中使用它,它带有.NET 4.0常规C#可以使用'dynamic'关键字处理动态绑定,就像t4一样。没有人能推断出它。如果你把工作表定义为动态的,那么你应该很好。我确实看到了常规C#和T4之间的不同结果——不需要在C#中定义任何
dynamic
,我引用的这一行很好。我尝试在T4中将
xlsheet
更改为
dynamic
,但这也导致了一个错误:
预定义类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或导入
编译转换:找不到编译动态表达式所需的一个或多个类型。是否缺少对Microsoft.CSharp.dll和System.Core.dll的引用?
。我没有缺少这些引用,并且导入建议的类型也不起作用。@GarethJ您是对的,我还必须添加一些程序集引用才能使其起作用(因此我缺少对
Microsoft.CSharp
System.Core
)的引用)。谢谢您使用的是哪一版本的t4?不确定如何检查t4的版本,但我在Visual C#2010 Express中使用它,带有.NET 4.0常规C#可以使用'dynamic'关键字处理动态绑定,t4也可以。没有人能推断出它。如果你把工作表定义为动态的,那么你应该很好。我确实看到了常规C#和T4之间的不同结果——不需要在C#中定义任何
dynamic
,我引用的这一行很好。我尝试在T4中将
xlsheet
更改为
dynamic
,但这也导致了一个错误:
预定义类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或导入
编译转换:找不到编译动态表达式所需的一个或多个类型。是否缺少对Microsoft.CSharp.dll和System.Core.dll的引用?
。我没有缺少这些引用,并且导入建议的类型也不起作用。@GarethJ您是对的,我还必须添加一些程序集引用才能使其起作用(因此我缺少对
Microsoft.CSharp
System.Core
)的引用)。谢谢还有一个解决办法,但它相当丑陋。您可以使用T4的compilerOptions参数将相当于“嵌入互操作类型”标志的命令行发送到编译器。您应该删除对interop DLL的assebmly引用,而是将followign参数添加到模板指令中。不幸的是,在没有环境变量的情况下需要完整路径。还有一个解决办法,但它相当丑陋。您可以使用T4的compilerOptions参数将相当于“嵌入互操作类型”标志的命令行发送到编译器。您应该删除对interop DLL的assebmly引用,而是将followign参数添加到模板指令中。不幸的是,在没有环境变量的情况下需要完整路径。