我想基于枚举值生成一堆类似的类。这些类在结构上将密切相关,但由于C#的类型安全性,使用继承来解决此问题并不可行。因此优选使用T4。就我而言,我想在元编程代码中使用匿名类型。
这是一个最小的片段,目的是说明我的使用模式,这也是我遇到的问题的例子:
using System;
using System.Windows.Data;
using System.Globalization;
using System.Windows;
using Fin4.Controls.Core;
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var enum_values = new dynamic[] {
new { EnumName = "HoverDatePicker.Mode", Value = "View"},
new { EnumName = "HoverDatePicker.Mode", Value = "Mode"},
new { EnumName = "Frequency", Value = "Monthly"},
new { EnumName = "Frequency", Value = "Weekly"}
};
#>
<#
for(int i = 0; i < enum_values.Length; i++)
{ #>
public class <#= enum_values[i].Value #>VisibilityConverter : IValueConverter
{
}
<#
} #>
它保存在名为example.tt
的文件中。为此文件选择的自定义工具为TextTemplatingFileGenerator
。当我(尝试)编译我的解决方案时,会生成以下输出:
ErrorGeneratingOutput
还会生成以下错误:
Severity Code Description Project File Line Suppression State
Error CS0116 A namespace cannot directly contain members such as fields or methods Fin4 x:\code\project\project\Controls\example.cs 1 Active
Error CS0103 The name 'ErrorGeneratingOutput' does not exist in the current context. Fin4 x:\code\project\project\Controls\example.cs 1 Active
Error Compiling transformation: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' Fin4 X:\code\project\project\Controls\example.tt 25
我首次尝试解决此问题是添加对Microsoft.CSharp
的引用。我的参考指向以下dll:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\Microsoft.CSharp.dll
这并没有解决问题。我第二次尝试解决此问题的方法是将自定义工具设置更改为TextTemplatingFilePreprocessor
。这产生了一个看起来与我想要的东西完全不同的文件,所以这也没有解决问题。
似乎很明显阻止TextTemplatingFileGenerator
工具使用C#.NET 4.0的匿名输入功能。但我不明白如何实现这一点。我做了很多谷歌搜索,似乎没有其他人有这个问题。
如果有人可以帮我弄清楚如何使用T4类生成器的匿名类型,那将是非常有帮助的。所以提前谢谢大家!
答案 0 :(得分:0)
我最终通过明确指定来完成这项工作,C#4.0应该用于元编程:
<# // Specify the C# version being used is 4.0 #>
<#@ Assembly Name="System.Core, Version=4.0.0.0, Culture=neutral" #>
<#@ Assembly Name="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral" #>
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var enum_nvs = new dynamic[] {
new { EnumName = "HoverDatePicker.Mode", EnumValue = "View"},
new { EnumName = "HoverDatePicker.Mode", EnumValue = "Edit"},
new { EnumName = "Frequency", EnumValue = "Monthly"},
new { EnumName = "Frequency", EnumValue = "Weekly"}
};
#>
<#
for(int i = 0; i < enum_values.Length; i++)
{ #>
public class <#= enum_values[i].Value #>VisibilityConverter : IValueConverter
{
}
<#
} #>
答案 1 :(得分:0)
原始问题可以通过删除不需要的动态关键字来解决:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var enum_values = new /* OMIT dynamic */ [] {
new { EnumName = "HoverDatePicker.Mode", Value = "View"},
new { EnumName = "HoverDatePicker.Mode", Value = "Mode"},
new { EnumName = "Frequency", Value = "Monthly"},
new { EnumName = "Frequency", Value = "Weekly"}
};
#>
<#
for(int i = 0; i < enum_values.Length; i++)
{ #>
public class <#= enum_values[i].Value #>VisibilityConverter : IValueConverter
{
}
<#
} #>