C#泛型包装器生成器

时间:2013-04-17 07:05:30

标签: c# .net generics reflection code-generation

我正在寻找一个代码生成器(最好带有源代码),它允许我为我的代码中的泛型类生成包装类(使用反射)。

我已经做了一些搜索,但似乎无法找到任何可以做我需要的东西,所以我想在我开始写自己之前我会问这里。最终,我可能不得不自己编写,但如果某人已经写过这样的内容,我想至少先搞清楚。

解释我想要它做什么有点困难,但是生成器应该允许我指定我希望它为哪些泛型类生成包装器。它应该通过我指定的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;}
}

1 个答案:

答案 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)) #>>
<#  }
#>

希望这有帮助