Je ne suis pas sûr que vous voulez vraiment faire ce que vous dites que vous voulez faire, mais ce n'est pas pour moi que de raison!
Vous ne pouvez pas ajouter des propriétés à une classe après qu'il a été JITed.
Le plus proche que vous pourriez obtenir serait de créer dynamiquement un sous-type avec la Réflexion.Émettre et de copier les champs existants, mais vous auriez à jour toutes les références à l'objet vous-même.
Vous aussi ne pas être en mesure d'accéder à ces propriétés au moment de la compilation.
Quelque chose comme:
public class Dynamic
{
public Dynamic Add<T>(string key, T value)
{
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Dynamic.dll");
TypeBuilder typeBuilder = moduleBuilder.DefineType(Guid.NewGuid().ToString());
typeBuilder.SetParent(this.GetType());
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(key, PropertyAttributes.None, typeof(T), Type.EmptyTypes);
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_" + key, MethodAttributes.Public, CallingConventions.HasThis, typeof(T), Type.EmptyTypes);
ILGenerator getter = getMethodBuilder.GetILGenerator();
getter.Emit(OpCodes.Ldarg_0);
getter.Emit(OpCodes.Ldstr, key);
getter.Emit(OpCodes.Callvirt, typeof(Dynamic).GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(typeof(T)));
getter.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getMethodBuilder);
Type type = typeBuilder.CreateType();
Dynamic child = (Dynamic)Activator.CreateInstance(type);
child.dictionary = this.dictionary;
dictionary.Add(key, value);
return child;
}
protected T Get<T>(string key)
{
return (T)dictionary[key];
}
private Dictionary<string, object> dictionary = new Dictionary<string,object>();
}
Je n'ai pas de VS installé sur cette machine, alors laissez-moi savoir si il y a de gros bugs (et bien d'autres... que le massif des problèmes de performances, mais je n'ai pas écrit le cahier des charges!)
Maintenant, vous pouvez utiliser:
Dynamic d = new Dynamic();
d = d.Add("MyProperty", 42);
Console.WriteLine(d.GetType().GetProperty("MyProperty").GetValue(d, null));
Vous pouvez également l'utiliser comme une propriété classique dans une langue qui prend en charge la liaison tardive (par exemple, VB.NET)