我正在寻找一个代码生成器(最好带有源代码),它允许我为我的代码中的泛型类生成包装类(使用反射)。
我已经做了一些搜索,但似乎无法找到任何可以做我需要的东西,所以我想在我开始写自己之前我会问这里。最终,我可能不得不自己编写,但如果某人已经写过这样的内容,我想至少先搞清楚。
解释我想要它做什么有点困难,但是生成器应该允许我指定我希望它为哪些泛型类生成包装器。它应该通过我指定的DLL中的类型来确定哪些类型适合基于泛型类中的where约束。我在linqpad中编写了一些示例代码,并在“Generated Code”部分中输出了示例。正如您所看到的,它可以生成所有类的组合,它可以基于泛型类中指定的约束。
为什么我要这样做?我有很多泛型类,每个类都有很多类型参数(其中很多都有超过10种类型的参数),我希望简化客户端代码(这也需要一些自定义工作以及毯子生成的代码生成器组合可能,但我可以处理)。完成之后,我可以将底层泛型类重构为更简单(不影响客户端代码),并且不需要与此时一样多的类型参数,这在此阶段是不可能的。
void Main()
{
var x = new GenBothFooAgainBarAgain();
var y = new GenFFoo();
var z = new GenFFooAgain();
var a = new GenBothWithChildFooBarFooChild();
var b = new GenBothWithChildFooBarAgainFooChild();
}
//////////////////////////////////Generated code ////////////////////////////////////
public class GenBothFooBar : GenBoth<Foo, Bar> {}
public class GenBothFooAgainBar : GenBoth<FooAgain, Bar> {}
public class GenBothFooBarAgain : GenBoth<Foo, BarAgain> {}
public class GenBothFooAgainBarAgain : GenBoth<FooAgain, BarAgain>{}
public class GenFFoo : GenF<Foo>{}
public class GenFFooAgain : GenF<FooAgain>{}
public class GenBothWithChildFooBarFooChild : GenBothWithChild<Foo, Bar, FooChild> {}
//public class GenBothWithChildFooAgainBarFooChild : GenBothWithChild<FooAgain, Bar, FooChild> {} - illegal - Don't generate this as FooChild doesn't inherit from FooAgain
public class GenBothWithChildFooBarAgainFooChild : GenBothWithChild<Foo, BarAgain, FooChild> {}
//public class GenBothWithChildFooAgainBarAgainFooChild : GenBothWithChild<FooAgain, BarAgain, FooChild>{} - illegal - Don't generate this as FooChild doesn't inherit from FooAgain
//////////////////////////////////Generated code ////////////////////////////////////
public class Foo : IFoo
{
public string foo {get; set;}
}
public class FooChild : Foo, IFooChild
{
public string fooChild {get; set;}
}
public class Bar : IBar
{
public string bar {get; set;}
}
public class FooAgain : IFoo
{
public string foo {get; set;}
}
public class BarAgain : IBar
{
public string bar {get; set;}
}
public class GenF<F>
where F: class, IFoo, new()
{
}
public class GenBoth<F, B>
where F: class, IFoo, new()
where B: class, IBar, new()
{
}
public class GenBothWithChild<F, B, FChild>
where F: class, IFoo, new()
where B: class, IBar, new()
where FChild: class, F, IFooChild, new()
{
}
public interface IFooChild
{
string fooChild {get; set;}
}
public interface IFoo
{
string foo {get; set;}
}
public interface IBar
{
string bar {get; set;}
}
答案 0 :(得分:1)
对于使用c#/ .net知识生成代码,我会指出使用T4 - 随Visual Studio免费提供的Microsoft软件文本模板引擎。感觉就像C#和ASP.NET之间的混合,所以你应该能够快速潜入。
使用设计时模板,您可以像平常一样指定现有的程序集并反映它们,甚至可以使用Visual Studio Automation CodeModel获取有关当前解决方案中的类的信息并生成来自它的代码。在构建项目之前,将在Visual Studio中生成此代码。
使用运行时模板,您可以&#34;准备&#34;如何在设计时生成代码的逻辑,为它提供一个程序列表,以便在运行时处理和生成代码。
不幸的是,Visual Studio缺少T4模板的编辑功能,但有tangible's T4 Editor之类的免费工具。
此代码段可用于T4模板,并查找mscorlib.dll中的所有泛型类,并将它们写入输出文件中:
<#
foreach(System.Reflection.TypeInfo type in typeof(string).Assembly
.DefinedTypes
.Where(t => t.ContainsGenericParameters))
{
#><#= type.Name #><<#= string.Join(", ", type.GenericTypeParameters.Select(tp => tp.Name)) #>>
<# }
#>
希望这有帮助