我有一个具有T4运行时模板的DLL和一个通过方法返回该模板实例的类(模板名称为Query.tt,它生成了Query.cs类):
来自dll的模板:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ template debug="true" #>
<#@ parameter name="TestObj" type="TemplateDLL.Class2" #>
Hellow <#= this.TestObj.s #>!
Hellow <#= this.TestObj.x #>!
来自dll的课程:
namespace TemplateDLL
{
public class Class1
{
public Query getQueryTemplate()
{
return new Query();
}
}
}
我正在使用Reflections:
将此dll加载到另一个项目中using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace TestDynTemplate2
{
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(@"D:\somedllpath\TemplateDLL.dll");
dynamic c = Activator.CreateInstance(DLL.GetType("TemplateDLL.Class1"));
var templateInstance = c.getQueryTemplate();
TemplateDLL.Class2 c2 = new TemplateDLL.Class2();
c2.x = 3;
c2.s = "cdfafdafa";
templateInstance.Session = new Dictionary<string, object>();
templateInstance.Session.Add("TestObj", c2);
templateInstance.Initialize();
var generatedCode = templateInstance.TransformText();
Console.WriteLine(generatedCode);
}
}
}
我在两个项目中都有(在dll项目中和在dll调用项目中)我实例化的一个类(TemplateDLL.Class2)的定义(在调用dll项目中)并且我将实例传递给dll函数生成模板。我传递的对象用在dll中的模板中。
namespace TemplateDLL
{
class Class2
{
public int x;
public string s;
}
}
一切正常,直到在模板中抛出System.InvalidCastException时在模板中使用该对象:[A] TemplateDLL.Class2无法强制转换为[B] TemplateDLL.Class2。并且它告诉我类型A和B的起源不一样。
如何使这项工作?我是c#和T4的新手。
答案 0 :(得分:0)
在C#(以及一般的.NET)中,相同的定义并不意味着同一个类。
在程序集A中声明的 Class2
和程序集B中声明的Class2
是完全不同的类(巧合地共享相同的名称空间和类名),因为类的全名和程序集都定义了它(其中还包括处理器体系结构和公钥,有关详细信息,请参阅GetType()
on MSDN。
您必须共享汇编,您可以将类型或副本(例如通过Reflection)从一种类型声明为另一种类型。像这样:
var instanceInBType = instanceInB.GetType();
foreach (var fieldInA in instanceFromA.GetType().GetFields())
{
var fieldInB = instanceInBType.GetField(field.Name);
var valueInA = fieldInA.GetValue(instanceFromA);
fieldInB.SetValue(instanceInB, valueInA);
}
实际上,您必须接受通用 object
参数(instanceFromA
),创建局部变量instanceInB
并按字段从A到B复制字段。当然,共享类型定义肯定更好......