我正在寻找一个代码生成器(最好带有源代码),它允许我为我的代码中的泛型类生成包装类(使用反射)。
我做了一些搜索,但似乎找不到任何可以在这里做我需要的东西,所以我想在我开始写自己的之前先问这里。最终,我可能不得不自己写,但如果有人已经写过这样的东西,我至少想抢占先机。
解释我想要它做什么有点困难,但是生成器应该允许我指定我希望它为哪些泛型类生成包装器。它应该检查我指定的 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;}
}