Jump to content
Tuts 4 You

TypeBuilder Class emiting - classes uses each other


CodeExplorer

Recommended Posts

Posted (edited)

If we would have this class:

    public class CentroidCluster<TCollection, TData, TCentroid, TCluster> : Cluster<TCollection, TData, TCluster> where TCollection : IMulticlassScoreClassifier<TData, int>, ICentroidClusterCollection<TData, TCentroid, TCluster> where TCluster : CentroidCluster<TCollection, TData, TCentroid, TCluster>, new()
    {
    
    }

I would just do this:
    public class DerivTCollection : IMulticlassScoreClassifier<int, int>, ICentroidClusterCollection<int, int, CentroidClusterDeriv>
    {
    
    }
        
    public class CentroidClusterDeriv : CentroidCluster<DerivTCollection, int, int, CentroidClusterDeriv>
    {
    
    }

we successfully derived class CentroidCluster
but now the problem: how we could do with reflection since those classes uses each other
https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.typebuilder?view=net-9.0
TypeBuilder final Type value is calculated with Type t = tb.CreateType();
but the problem is that class is not yet finished;
Any solution?
 

Edited by CodeExplorer
  • Like 1
  • The title was changed to TypeBuilder Class emiting - classes uses each other
Posted

https://stackoverflow.com/questions/6735274/why-am-i-getting-this-exception-when-emitting-classes-that-reference-each-other

but not working in my case;

System.ArgumentException: Type must be a type provided by the runtime.
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at BabelDeobfuscator.Protections.MethodEncryption.VMDecryptor.GetGenericInstance(Type gtype, Assembly asm) in d:\Projects2021-2024\NET\Babel-Deobfuscator\Babel-Deobfuscator\MethodEncryption\VMDecryptor.cs:line 835
   at BabelDeobfuscator.Protections.MethodEncryption.VMDecryptor.Testing(Assembly asm) in d:\Projects2021-2024\NET\Babel-Deobfuscator\Babel-Deobfuscator\MethodEncryption\VMDecryptor.cs:line 1141
   at BabelDeobfuscator.Protections.MethodEncryption.VMDecryptor.run(ModuleDefMD module, Assembly asm) in d:\Projects2021-2024\NET\Babel-Deobfuscator\Babel-Deobfuscator\MethodEncryption\VMDecryptor.cs:line 53
   at BabelDeobfuscator.Program.Main(String[] args) in d:\Projects2021-2024\NET\Babel-Deobfuscator\Babel-Deobfuscator\Program.cs:line 289

 

  • Like 1
Posted (edited)

More examples:
https://stackoverflow.com/questions/21035470/using-reflection-emit-to-implement-generic-interface

If I left as TypeBuilder throws the above error; no Domain_TypeResolve is called.
it will works only if I create the Type using CreateType of TypeBuilder
like this:
            if (rtypes[0] is System.Reflection.Emit.TypeBuilder)
            rtypes[0] = ((System.Reflection.Emit.TypeBuilder)rtypes[0]).CreateType();

interesting is that types created multiple times are equal:

         Type type1 = typeUseItself.CreateType();
         Type type2 = typeUseItself.CreateType();
            
         if (type1.Equals(type2))
         {
         Console.WriteLine("Cool!");
         }

 

 

Edited by CodeExplorer
  • Like 1
Posted
			var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);
			var module = assembly.DefineDynamicModule("Test");
	
			var typeOne = module.DefineType("TypeOne", TypeAttributes.Public);
			var typeTwo = module.DefineType("TypeTwo", TypeAttributes.Public);
			
			TypeConflictResolver resolver = new TypeConflictResolver();
			resolver.Bind(AppDomain.CurrentDomain);
			resolver.AddTypeBuilder(typeOne);
			resolver.AddTypeBuilder(typeTwo);
									
			Type GenericI2 = typeof(Interface<,>).MakeGenericType(new Type[]{typeof(int), typeOne});
			typeTwo.AddInterfaceImplementation(GenericI2);
			
			Type[] tbCentroidCluster11X = new Type[] {typeTwo, typeof(int), typeof(int), typeOne};
			Type tCentroidCluster11X = typeof(CentroidClusterSimplified<,,,>).MakeGenericType(tbCentroidCluster11X);
			typeOne.SetParent(tCentroidCluster11X);

			typeOne.CreateType();
			typeTwo.CreateType();

I can't see nothing wrong with the above code; but it throws exception
System.TypeLoadException: Could not load type 'TypeOne' from assembly 'Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
   at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
   at System.Reflection.Emit.TypeBuilder.CreateType()
 

  • Like 1
Posted

I think this is a framework limitation and can't be done. :sad2:
I would rather spend time on realizable things.
 

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...