如何在生成的动态类型上抑制默认构造函数

时间:2017-07-28 23:36:53

标签: .net codegen

在.NET中创建动态类型时,会生成默认构造函数。我该如何压制它?

var typeBuilder = moduleBuilder.DefineType(
    type.FullName,
    TypeAttributes.NotPublic | TypeAttributes.BeforeFieldInit);

1 个答案:

答案 0 :(得分:1)

这记录在"备注部分" 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());
}