使用TypeBuilder为基类创建传递构造函数

假设我有一个SpaceShip类,如下所示:

 public class SpaceShip { public SpaceShip() { } public SpaceShip(IRocketFuelSource fuelSource) { } } 

我想使用TypeBuilder在运行时创建一个inheritance自SpaceShip的类型,并为SpaceShip中的每个类型定义一个构造函数。 除了将参数传递给父(“传递”构造函数)之外,我不需要构造函数实际执行任何操作。 例如,如果用C#表示,生成的类型看起来像这样:

 public class SpaceShipSubClass : SpaceShip { public SpaceShipSubClass() : base() { } public SpaceShipSubClass(IRocketFuelSource fuelSource) : base(fuelSource) { } } 

为了使事情复杂化,我实际上并不知道生成类型将inheritance到哪个类直到运行时(因此我将不得不考虑任意数量的构造函数,可能使用默认参数)。

这可能吗? 我想如果我有一个总体方向可以解决这个问题,那就是我对TypeBuilder完全不TypeBuilder

谢谢!

好吧,我在网上找不到任何东西,所以我最终实现了自己的。 这应该有助于开始编写某种代理的任何人。

 public static class TypeBuilderHelper { /// Creates one constructor for each public constructor in the base class. Each constructor simply /// forwards its arguments to the base constructor, and matches the base constructor's signature. /// Supports optional values, and custom attributes on constructors and parameters. /// Does not support n-ary (variadic) constructors public static void CreatePassThroughConstructors(this TypeBuilder builder, Type baseType) { foreach (var constructor in baseType.GetConstructors()) { var parameters = constructor.GetParameters(); if (parameters.Length > 0 && parameters.Last().IsDefined(typeof(ParamArrayAttribute), false)) { //throw new InvalidOperationException("Variadic constructors are not supported"); continue; } var parameterTypes = parameters.Select(p => p.ParameterType).ToArray(); var requiredCustomModifiers = parameters.Select(p => p.GetRequiredCustomModifiers()).ToArray(); var optionalCustomModifiers = parameters.Select(p => p.GetOptionalCustomModifiers()).ToArray(); var ctor = builder.DefineConstructor(MethodAttributes.Public, constructor.CallingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); for (var i = 0; i < parameters.Length; ++i) { var parameter = parameters[i]; var parameterBuilder = ctor.DefineParameter(i + 1, parameter.Attributes, parameter.Name); if (((int)parameter.Attributes & (int)ParameterAttributes.HasDefault) != 0) { parameterBuilder.SetConstant(parameter.RawDefaultValue); } foreach (var attribute in BuildCustomAttributes(parameter.GetCustomAttributesData())) { parameterBuilder.SetCustomAttribute(attribute); } } foreach (var attribute in BuildCustomAttributes(constructor.GetCustomAttributesData())) { ctor.SetCustomAttribute(attribute); } var emitter = ctor.GetILGenerator(); emitter.Emit(OpCodes.Nop); // Load `this` and call base constructor with arguments emitter.Emit(OpCodes.Ldarg_0); for (var i = 1; i <= parameters.Length; ++i) { emitter.Emit(OpCodes.Ldarg, i); } emitter.Emit(OpCodes.Call, constructor); emitter.Emit(OpCodes.Ret); } } private static CustomAttributeBuilder[] BuildCustomAttributes(IEnumerable customAttributes) { return customAttributes.Select(attribute => { var attributeArgs = attribute.ConstructorArguments.Select(a => a.Value).ToArray(); var namedPropertyInfos = attribute.NamedArguments.Select(a => a.MemberInfo).OfType().ToArray(); var namedPropertyValues = attribute.NamedArguments.Where(a => a.MemberInfo is PropertyInfo).Select(a => a.TypedValue.Value).ToArray(); var namedFieldInfos = attribute.NamedArguments.Select(a => a.MemberInfo).OfType().ToArray(); var namedFieldValues = attribute.NamedArguments.Where(a => a.MemberInfo is FieldInfo).Select(a => a.TypedValue.Value).ToArray(); return new CustomAttributeBuilder(attribute.Constructor, attributeArgs, namedPropertyInfos, namedPropertyValues, namedFieldInfos, namedFieldValues); }).ToArray(); } } 

用法(假设您有一个TypeBuilder对象 – 请参阅此处的示例):

 var typeBuilder = ...; // TypeBuilder for a SpaceShipSubClass typeBuilder.CreatePassThroughConstructors(typeof(SpaceShip)); var subType = typeBuilder.CreateType(); // Woo-hoo, proxy constructors!