Czy w języku C# można utworzyć typ w środowisku wykonawczym, który dziedziczy po klasie ogólnej, w której parametrem szablonu dla klasy bazowej jest konstruowana bieżąca klasa? Będzie to skompilować grzywny:Utwórz typ "MyClass: OtherClass <MyClass> {}" w czasie wykonywania?
// I have this class:
public class OtherClass<T>
where T : OtherClass<T>
{ }
// I want to create this at runtime:
public class MyClass : OtherClass<MyClass>
{ }
ale nie jestem pewien, jak stworzyć MyClass
użyciu System.Reflection.Emit.ModuleBuilder.TypeBuilder
:
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,
typeof(MyClass)); // How to specify inheritance?
// populate properties, fields, methods, etc., emit...
tb.CreateType();
Czy to możliwe?
Edit - Na podstawie odpowiedzi tak daleko, próbowałem to:
public class OtherClass<T>
where T : OtherClass<T>
{ }
public static void CreateSimple()
{
AssemblyName asn = new AssemblyName("test");
AssemblyBuilder asb = AppDomain.CurrentDomain.DefineDynamicAssembly(
asn, AssemblyBuilderAccess.RunAndSave, @"D:\test_asms");
ModuleBuilder modb = asb.DefineDynamicModule("test", "test.dll");
try
{
TypeBuilder tb = modb.DefineType(
"MyClass",
TypeAttributes.Public | TypeAttributes.Class);
Type my = tb.CreateType();
tb.SetParent(typeof(OtherClass<>).MakeGenericType(my));
my = tb.CreateType();
}
catch (Exception e)
{
throw;
}
}
ale uzyskać ten wyjątek:
GenericArguments[0], 'MyClass', on 'MyProject.Factory+OtherClass`1[T]'
violates the constraint of type 'T'.
Ale ... Dlaczego chcesz to zrobić? – LightStriker
@LightStriker: Ponieważ 99% typów 'MyClass' jest zdefiniowanych w kodzie, ale kilka musi być utworzonych po wdrożeniu (modele NHibernate) i' OtherClass' ogranicza, że typ ogólny to taki, który dziedziczy po 'OtherClass'. – wes
Edytowałem swoją odpowiedź - to zadziała teraz, bez wyjątku GenericArgument. – gracchus