在 .NET 中创建动态类型时,会生成默认构造函数。我该如何压制它?
var typeBuilder = moduleBuilder.DefineType(
type.FullName,
TypeAttributes.NotPublic | TypeAttributes.BeforeFieldInit);
这记录在TypeBuilder.DefineConstructor Method的“备注部分”中。
如果您没有为动态类型定义构造函数,则会自动提供默认构造函数,并调用基类的默认构造函数。
如果为动态类型定义构造函数,则不提供默认构造函数。除了您定义的构造函数之外,您还有以下选项可以提供默认构造函数:
如果您想要一个简单地调用基类的默认构造函数的默认构造函数,您可以使用 DefineDefaultConstructor 方法来创建一个(并且可以选择限制对它的访问)。不要为此默认构造函数提供实现。如果这样做,当您尝试使用构造函数时会引发异常。调用 CreateType 方法时不会引发异常。
如果你想要一个不只是调用基类的默认构造函数,或者调用基类的另一个构造函数,或者完全做其他事情的默认构造函数,你必须使用 TypeBuilder.DefineConstructor 方法来创建一个,并提供您自己的实现。
这种行为与您在没有显式定义默认构造函数的情况下定义一个类没有什么不同;编译器生成一个调用基本构造函数的公共默认构造函数。
如果你想要一个私有的默认构造函数,那么:
ConstructorBuilder ctor = typeBuilder.DefineDefaultConstructor(MethodAttributes.Private);
编辑:
在评论中,有人提到一个static
类没有构造函数。在与 Reflector 来回折腾后,我确定以下将创建一个静态动态类,该类具有与 c# 生成的相同的默认属性。
public void Test()
{
AssemblyName asmName = new AssemblyName("TestAsmStatic");
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");
TypeBuilder tb = mb.DefineType("StaticType", TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit | TypeAttributes.Abstract);
Type t = tb.CreateType();
ab.Save(asmName.Name + ".dll");
ConstructorInfo[] ci = t.GetConstructors((System.Reflection.BindingFlags)(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static));
Console.WriteLine(ci.Length.ToString());
}