【发布时间】:2013-04-09 20:08:19
【问题描述】:
我正在寻找一个代码生成器(最好有源代码),它允许我为我的代码中的泛型类生成包装类(使用反射)。
我已经进行了一些搜索,但似乎找不到任何可以在这里满足我需要的东西,所以我想在开始编写自己的内容之前先在这里问一下。最终,我可能不得不自己写,但如果有人已经写过这样的东西,我至少想抢先一步。
解释我想要它做什么有点困难,但是生成器应该允许我指定我希望它为哪些泛型类生成包装器。它应该检查我指定的 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;}
}
【问题讨论】:
-
如果我自己写的话,这看起来是一个好的开始 - stackoverflow.com/questions/8219725/…
-
有趣的问题,但是这可能是很多的类型。假设有 10 个泛型类型参数(尽管您提到超过 10 个)和 3 个在编译时已知的可以满足每个泛型类型约束的类型,那么这就是为一个创建的 3^10 个类型(~60K 类型)泛型类型定义。不过,好问题,+1
-
是的,这就是为什么我可能需要编写一些自定义逻辑来防止这么多组合:) 虽然它可能不是那么糟糕,因为我的类型中的约束非常严格,以便使如果您混合和匹配不在一起的类型,编译器会抱怨。我想我会看看情况如何。看起来我要在这个阶段编写自己的代码,我会在完成后发布代码(可能需要一段时间才能开始使用它:)
标签: c# .net generics reflection code-generation