c#泛型包装器生成器
本文关键字:包装 泛型 | 更新日期: 2023-09-27 18:09:48
我正在寻找一个代码生成器(最好是源代码),这将允许我生成包装类(使用反射)的通用类,我在我的代码。
我做了一些搜索,但似乎找不到任何可以做我需要的东西,所以我想在我开始写我自己的之前,我应该在这里问一下。最终,我可能不得不写我自己的,但如果有人已经写过这样的东西,我希望至少能领先一步。
解释我想让它做什么有点困难,但是生成器应该允许我指定我想让它为哪些泛型类生成包装器。它应该遍历我指定的dll中的类型,以根据泛型类中的where约束来确定哪些类型适合。我在linqpad中编写了一些示例代码,并在"生成的代码"一节中提供了示例输出。正如你所看到的,它可以根据在泛型类中指定的约束生成所有类的组合。
我为什么要这样做?我有相当多的泛型类,每个都有许多类型参数(其中许多有超过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;}
}
对于使用c#/.net知识生成代码,我建议您使用T4 -微软的文本模板引擎,它是Visual Studio免费提供的。它感觉像是c#和ASP的混合体。. NET,所以你应该能够快速上手。
使用设计时模板,您可以指定现有的程序集并反映它们,就像您通常做的那样,甚至可以使用Visual Studio Automation CodeModel来获取有关当前解决方案中的类的信息并从中生成代码。此代码将在构建项目之前在Visual Studio中生成。
使用运行时模板,您将"准备"如何在设计时生成代码的逻辑,为其提供在运行时处理和生成代码的程序集列表。
遗憾的是,Visual Studio缺乏T4模板的编辑功能,但有免费的工具,如有形的T4编辑器。
这个代码片段可以在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)) #>>
<# }
#>
希望能有所帮助