Create type “MyClass : OtherClass { }” at runtime?

后端 未结 3 765
灰色年华
灰色年华 2021-01-02 09:48

Is it possible in C# to create a type at runtime that inherits from a generic class where the template parameter for the base class is the current class being constructed? T

3条回答
  •  有刺的猬
    2021-01-02 09:56

    Edit : Here is my final working answer :

            AssemblyName asn = new AssemblyName("test.dll");
            AssemblyBuilder asb = AppDomain.CurrentDomain.DefineDynamicAssembly(
                asn, AssemblyBuilderAccess.RunAndSave, @"D:\test_assemblies");
    
            ModuleBuilder modb = asb.DefineDynamicModule("test", "test.dll");
    
            TypeBuilder tb = modb.DefineType(
                "test",
                TypeAttributes.Public | TypeAttributes.Class);
            // Typebuilder is a sub class of Type
            tb.SetParent(typeof(OtherClass<>).MakeGenericType(tb));
            var t2 = tb.CreateType();
            var i = Activator.CreateInstance(t2);
    

    The trick is to call SetParent with a parametrised generic type, the parameter is the typebuilder of the type being constructed itself.


    Use the TypeBuilder.SetParent(Type parent) method.

    Be careful when using it, exception throwing is deferred to CreateType call :

    If parent is null, Object is used as the base type.

    In the .NET Framework versions 1.0 and 1.1, no exception is thrown if parent is an interface type, but a TypeLoadException is thrown when the CreateType method is called.

    The SetParent method does not check for most invalid parent types. For example, it does not reject a parent type that has no default constructor when the current type has a default constructor, it does not reject sealed types, and it does not reject the Delegate type. In all these cases, exceptions are thrown by the CreateType method.

    To build your generic type OtherClass, use the MakeGenericType method :

    var genericType = typeof(OtherClass<>).MakeGenericType(typeof(MyClass));
    

提交回复
热议问题