Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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# 在每次生成期间,使用不同的参数从模板生成代码_C#_Code Generation_T4_Template Engine - Fatal编程技术网

C# 在每次生成期间,使用不同的参数从模板生成代码

C# 在每次生成期间,使用不同的参数从模板生成代码,c#,code-generation,t4,template-engine,C#,Code Generation,T4,Template Engine,我正在用C#编写一个有点复杂的库,需要从模板自动生成大量样板代码。具体而言,我希望实现以下目标: public partial class $ClassName$<T> { /// ... /// ... /// ... /// (long documentation) public $ClassName$<TOut> Select(Func<T, TOut> selector, $OtherType$<TOut&

我正在用C#编写一个有点复杂的库,需要从模板自动生成大量样板代码。具体而言,我希望实现以下目标:

public partial class $ClassName$<T>
{
    /// ...
    /// ...
    /// ...
    /// (long documentation)
    public $ClassName$<TOut> Select(Func<T, TOut> selector, $OtherType$<TOut> other = null)
    {
        return base.Select(new $ClassName$<TOut>(other), selector);
    }
}
公共部分类$ClassName$
{
/// ...
/// ...
/// ...
///(长文档)
public$ClassName$Select(Func选择器,$OtherType$other=null)
{
返回base.Select(新的$ClassName$(其他),选择器);
}
}
(您可能会注意到,这实际上是一种模拟更高级类型参数的尝试,但这对问题并不特别重要)

但是,我不希望代码以“静态”的方式生成,就像“新建项”向导在VisualStudio中生成代码那样。这是因为模板本身实际上就是“代码”,并且可能会发生更改。无论何时更改模板,我都无法使用此样板代码手动重新生成所有类

这就是为什么我在寻找一种在每次构建期间或者在其他一些操作中生成此代码的方法。由于多个类将使用此样板代码(具有不同的模板参数),因此应该为使用它的每个类自动生成代码。同样重要的是,IntelliSense可以使用这些代码

我也在寻找一个用于编写这些模板的工具,可能还有一些管理它们的工具

有什么帮助吗


编辑:T4文本模板似乎正是我想要的。但是,如何创建一个模板的“多个实例”,每个实例具有不同的参数,并将每个实例与不同的类相关联?内置功能似乎只生成一个文件。

理论上,您可以在Visual Studio中使用分配给每个
$ClassName$
的模板来生成这样的代码。理论上,您可以在Visual Studio中使用分配给每个
$ClassName$
的模板来生成这样的代码理论上在Visual Studio中使用分配给每个
$ClassName$

的模板生成这样的代码您可以理论上在Visual Studio中使用分配给每个
$ClassName$
的模板生成这样的代码您考虑过使用吗?

您考虑过使用吗?

您考虑过使用吗您是否考虑过使用?

您可以按如下方式使用

.1。参数化T4

在生成中添加参数化-使用传统类变量或更长的块模板。它在处理过程中根据某些参数值等读取的文件

.2。控制生成,不管它是预编译的还是立即运行的

我将复制粘贴部分我如何处理代码生成的外部控制

    public Tuple<string, string>[] GetGeneratorContent(params string[] xmlFileNames)
{
    List<Tuple<string, string>> result = new List<Tuple<string, string>>();
    foreach(string xmlFileName in xmlFileNames)
    {
        TheBallCoreAbstractionType abs = LoadXml<TheBallCoreAbstractionType>(xmlFileName);
        CurrentAbstraction = abs;
        this.GenerationEnvironment.Clear();
        string content = TransformText();
        string outputFile = Path.GetFileNameWithoutExtension(xmlFileName) + ".designer.cs";
        result.Add(Tuple.Create(outputFile, content));
    }
    return result.ToArray();
}
公共元组[]GetGeneratorContent(参数字符串[]XmlFileName)
{
列表结果=新列表();
foreach(xmlFileNames中的字符串xmlFileName)
{
ballcoreabstractiontype abs=LoadXml(xmlFileName);
电流抽象=绝对值;
此.GenerationEnvironment.Clear();
字符串内容=TransformText();
字符串outputFile=Path.GetFileNameWithoutExtension(xmlFileName)+“.designer.cs”;
Add(Tuple.Create(outputFile,content));
}
返回result.ToArray();
}
上面值得注意的是TransformText(),它“正常”运行模板,在此之前是“this.GenerationEnvironment.Clear()”。在这一点上,设置了一些类变量,然后以filename+content的形式返回输出——当然,这可能只是File.WriteAllText(name,content)

为了进一步的兴趣-为了“大规模参数化”,我在下面添加了更多

免责声明我已经广泛研究了完全开放的T4自动化模块化方法。我将围绕此链接几个链接,因为虽然上面的答案已经有点紧凑,但T4控制的各种方式(特别是在原始问题的参数化管理案例中)是非常有趣和非常强大的艺术

也就是说,这里有几个完整的链接使用了VS2010和T4工具箱,但可以通过单击“转换所有模板”在后一个工作室中不使用T4工具箱的情况下运行:

T4演示从头开始,ADM部分用于通过T4实现的抽象控制

该方法在相当长一段时间前得到了T4团队的积极反馈:-):

从演示视频中可以看到关于可以实现什么的各种演示,但对于纯/高级T4,我推荐入门和高级T4:

您可以按如下方式制作

.1。参数化T4

在生成中添加参数化-使用传统类变量或更长的块模板。它在处理过程中根据某些参数值等读取的文件

.2。控制生成,不管它是预编译的还是立即运行的

我将复制粘贴部分我如何处理代码生成的外部控制

    public Tuple<string, string>[] GetGeneratorContent(params string[] xmlFileNames)
{
    List<Tuple<string, string>> result = new List<Tuple<string, string>>();
    foreach(string xmlFileName in xmlFileNames)
    {
        TheBallCoreAbstractionType abs = LoadXml<TheBallCoreAbstractionType>(xmlFileName);
        CurrentAbstraction = abs;
        this.GenerationEnvironment.Clear();
        string content = TransformText();
        string outputFile = Path.GetFileNameWithoutExtension(xmlFileName) + ".designer.cs";
        result.Add(Tuple.Create(outputFile, content));
    }
    return result.ToArray();
}
公共元组[]GetGeneratorContent(参数字符串[]XmlFileName)
{
列表结果=新列表();
foreach(xmlFileNames中的字符串xmlFileName)
{
ballcoreabstractiontype abs=LoadXml(xmlFileName);
电流抽象=绝对值;
此.GenerationEnvironment.Clear();
字符串内容=TransformText();
字符串outputFile=Path.GetFileNameWithoutExtension(xmlFileName)+“.designer.cs”;
Add(Tuple.Create(outputFile,content));
}
返回result.ToArray();
}
上面值得注意的是TransformText(),它“正常”运行模板,在此之前是“this.GenerationEnvironment.Clear()”。设置一些类变量,然后以filename+content的形式返回输出-当然,这可能只是File.WriteAllText(name,