2010-11-08 20 views
0

Je dois créer un type avec des propriétés lors de l'exécution. type doit être ressembler à ceci:Génération d'un type à l'exécution

public class RunTimeType : BaseType 
{ 

private string _field1; 

public string Property1 
    { 

    get { return _field1; } 
    set 
    { 
     if (_field1 != value) 
     { 
      _field1 = value; 
      OnAfterPropertySet("Property1"); 
     } 
    } 
    } 

} 

la question est de savoir comment créer Set méthode? Maintenant, j'utiliser le code que vous avez choisi:

var propertyName = "Property1"; 

var onAfterPropertySet = baseType.GetMethod("OnAfterPropertySet", 
               BindingFlags.Instance | BindingFlags.InvokeMethod | 
               BindingFlags.NonPublic, null, new[] { typeof(string) }, 
               null); 


ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); 
currSetIL.Emit(OpCodes.Ldarg_0); 
currSetIL.Emit(OpCodes.Ldarg_1); 
currSetIL.Emit(OpCodes.Stfld, field); 

currSetIL.Emit(OpCodes.Ldstr, propertyName); 
currSetIL.Emit(OpCodes.Call, onAfterPropertySet); 
currSetIL.Emit(OpCodes.Pop); 

currSetIL.Emit(OpCodes.Ret); 

mais quand j'essaie de définir la valeur à la propriété, exception est levée

+0

Qu'est-ce que Essaies-tu d'accomplir? Générer IL est rarement la meilleure solution. – SLaks

+0

Quelle exception obtenez-vous? – SLaks

+0

je reçois TargetInvocationException – Timur

Répondre

1

Vous n'êtes pas vraiment proche. Vous avez oublié le test d'égalité et passé le caché cet argument à la méthode d'instance. La meilleure façon de le faire est d'écrire le code en C# premier:

class Test { 
    private string _field1; 
    private void OnAfterPropertySet(string arg) { } 
    public string Property1 { 
     set { 
      if (_field1 != value) { 
       _field1 = value; 
       OnAfterPropertySet("Property1"); 
      } 
     } 
    } 
} 

rebâtis en mode de sortie alors jetez un oeil à l'produit IL avec ildasm.exe ou réflecteur:

IL_0000: ldarg.0 
    IL_0001: ldfld  string ConsoleApplication1.Test::_field1 
    IL_0006: ldarg.1 
    IL_0007: call  bool [mscorlib]System.String::op_Inequality(string, 
                    string) 
    IL_000c: brfalse.s IL_0020 
    IL_000e: ldarg.0 
    IL_000f: ldarg.1 
    IL_0010: stfld  string ConsoleApplication1.Test::_field1 
    IL_0015: ldarg.0 
    IL_0016: ldstr  "Property1" 
    IL_001b: call  instance void ConsoleApplication1.Test::OnAfterPropertySet(string) 
    IL_0020: ret 
0

Vous devez Ldarg_0 avant d'appeler onAfterPropertySet pour le paramètre this.