3

J'ai une stratégie pour résoudre les types de DLL référencés. Je suis bloqué sur essayer de résoudre les types qui sont définis dans l'assembly en cours de compilation. J'utilise les apis System.Reflection.Emit sans bibliothèques tierces.Je tente d'écrire un compilateur .NET en utilisant System.Reflection.Emit comment faire une résolution de type?

Par exemple:

class A {} 
class B 
{ 
    public A AnInstanceOfA {get; private set;} 
} 

Quelle est la meilleure façon de résoudre la référence B de A?

Qu'en est-ce:

class A 
{ 
    B AnInstanceOfB {get; set;} 
} 
class B 
{ 
    A AnInstanceOfA {get; set;} 
} 

où les classes contiennent des instances de l'autre.

Existe-t-il une meilleure façon de faire? Tous les modèles de conception que je devrais mettre en œuvre? Je préférerais utiliser uniquement les bibliothèques System.Reflection.Emit mais s'il y a une meilleure façon de le faire ou cela ne peut pas être fait avec, alors l'utilisation d'autres bibliothèques est acceptable.

Merci

+3

Type d'inférence! = Résolution des types dans les assemblages. L'inférence de type est la tâche de déduire statiquement des types de choses qui ne sont pas explicitement mentionnés dans le code source en fonction des preuves acquises à partir des façons dont elles sont utilisées (comme fait en F #). La résolution de types consiste simplement à rechercher des types en fonction de leur nom. Lequel voulez-vous dire? –

+0

Résoudre les types, désolé pour la confusion. –

Répondre

3

Pourriez-vous préciser la question que vous utilisez en (peut-être un code montrant un petit exemple de code qui ne fonctionne pas pour vous)? Parce que TypeBuilder dérive de Type, si vous essayez de définir des types mutuellement récursifs, vous pouvez passer les deux TypeBuilder s où vous voulez faire référence aux types.

EDIT

Il n'y a pas besoin de "résoudre" les types. Vous avez accès aux TypeBuilder pour chacun et vous pouvez les utiliser comme s'ils étaient des types entièrement définis. Voici un exemple qui génère le code que vous avez demandé dans votre mise à jour:

private void DefineAutoProp(string name, Type t, TypeBuilder tb) 
{ 
    var fldName = name.Substring(0, 1).ToLower() + name.Substring(1); 
    var fld = tb.DefineField(fldName, t, FieldAttributes.Private); 
    var prop = tb.DefineProperty(name, PropertyAttributes.None, t, null); 
    var getter = tb.DefineMethod("get_" + name, MethodAttributes.Public, t, null); 
    var ilg = getter.GetILGenerator(); 
    ilg.Emit(OpCodes.Ldarg_0); 
    ilg.Emit(OpCodes.Ldfld, fld); 
    ilg.Emit(OpCodes.Ret); 
    var setter = tb.DefineMethod("set_" + name, MethodAttributes.Public, typeof(void), new[] { t }); 
    ilg = setter.GetILGenerator(); 
    ilg.Emit(OpCodes.Ldarg_0); 
    ilg.Emit(OpCodes.Ldarg_1); 
    ilg.Emit(OpCodes.Stfld, fld); 
    ilg.Emit(OpCodes.Ret); 
    prop.SetGetMethod(getter); 
    prop.SetSetMethod(setter); 
} 

public void DefineTypes() 
{ 
    var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test"), AssemblyBuilderAccess.Run); 
    var mb = ab.DefineDynamicModule("test"); 
    var A = mb.DefineType("A", TypeAttributes.Public | TypeAttributes.Class); 
    var B = mb.DefineType("B", TypeAttributes.Public | TypeAttributes.Class); 
    DefineAutoProp("AnInstanceOfA", A, B); 
    DefineAutoProp("AnInstanceOfB", B, A); 
    A.CreateType(); 
    B.CreateType(); 
} 
+0

J'ai élaboré la question. S'il vous plaît voir la modification. Merci. –

+0

@wawa - voir mon edit pour un exemple de comment faire ce que vous demandez. – kvb

+0

Que se passe-t-il s'il existe d'autres méthodes et propriétés définies dans A et B? Puis-je utiliser TypeBuilder dans DefineAutoProp avant d'avoir fini de créer tous les membres du (des) type (s)? –

Questions connexes