Using emitted type as type parameter in Reflection.Emit
Asked Answered
C

2

7
[Name("Admin")]
public class TestAdmin : TestUserBase<TestAdmin>
{
    public TestAdmin(Type webDriverType) : base(webDriverType)
    {
    }
}

Currently, I have a bunch of classes of this form that I'd like to create at runtime using Reflection.Emit. However, I'm running into an issue when I attempt to add the parent - since the TestAdmin class doesn't exist before runtime, I don't know how to create

TestUserBase<TestAdmin>

Any ideas?

Cardcarrying answered 10/6, 2013 at 21:8 Comment(5)
Are you having trouble specifically because the argument to the base generic class is this class?Erotogenic
I believe you have a chicken and egg problem... The C# compiler may be able do this because it's probably not using Reflection.Emit to generate the IL. I'm not sure if there is a solution to this problem...Cutanddried
Does make-generic-method accept the type-builder? Actually, though, I do seem to recall some thorny chicken/egg areas that il-emit struggles with. Lately I'm using IKVM-reflection which has the same api as reflection-emit but which fixes a lot of these areasGyrate
@MarcGravell Lee's code works for me, I think this isn't one of the problematic cases.Store
@MichaelGunter Yes, that's been my issue. I think Lee's code will work, but haven't had a chance to test it yet.Cardcarrying
G
7

You can set the parent type using SetParent:

TypeBuilder tb = mb.DefineType("TestAdmin", TypeAttributes.Public);
tb.SetParent(typeof(TestUserBase<>).MakeGenericType(tb));

Type theType = tb.CreateType();
Gemina answered 10/6, 2013 at 21:49 Comment(0)
E
3

OK. I haven't been able to test this thoroughly, but I think this is possible. Try something like this:

Assuming your generic base class is already defined (i.e., you're not generating TestUserBase<T>), you should be able to do something like this:

var emittedType = module.DefineType("TestAdmin", TypeAttributes.Public | TypeAttributes.Class);
var baseType = typeof(TestUserBase<>).MakeGenericType(type);
emittedType.SetParent(baseType);

Of course, if TestUserBase<T> is begin generated, you can use this same logic using MakeGenericType on the dynamic type TestUserBase<T>. The SetParent logic is the same.

Erotogenic answered 10/6, 2013 at 21:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.