fork download
  1. using System;
  2. using System.Dynamic;
  3. using System.Reflection;
  4. using System.Collections.Generic;
  5. using static System.Console;
  6.  
  7. public class Dynamic : DynamicObject {
  8. Dictionary<string, object> dictionary = new Dictionary<string, object>();
  9.  
  10. public override bool TryGetMember(GetMemberBinder binder, out object result) => dictionary.TryGetValue(binder.Name, out result);
  11.  
  12. public override bool TrySetMember(SetMemberBinder binder, object value) {
  13. dictionary[binder.Name] = value;
  14. return true;
  15. }
  16.  
  17. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
  18. if (dictionary.ContainsKey(binder.Name)) {
  19. ((Action)dictionary[binder.Name]).Invoke(); //fiz gambi, precisa elaborar mais esta chamada para adequadar para qualquer tipo
  20. result = "Método dinâmico executou";
  21. return true;
  22. }
  23. try {
  24. result = (typeof(Dictionary<string, object>)).InvokeMember(binder.Name, BindingFlags.InvokeMethod, null, dictionary, args);
  25. } catch {
  26. result = "Resultado falho";
  27. WriteLine($"Executando método \"{binder.Name}\".");
  28. }
  29. return true;
  30. }
  31.  
  32. public void Print() {
  33. foreach (var pair in dictionary) {
  34. if (!(pair.Value is Delegate)) WriteLine(pair.Key + " " + pair.Value);
  35. }
  36. if (dictionary.Count == 0) WriteLine("Sem membros para listar");
  37. }
  38. }
  39.  
  40. public class Program {
  41. public static void Main(string[] args) {
  42. dynamic din = new Dynamic(); //precisa ser dynamic para o compilador não reclamar dos membros dinâmicos
  43. din.Nome = "Walla"; //criando membros dinamicamente
  44. din.Sobrenome = "C#";
  45. din.Action = new Action(() => WriteLine("Action Existe")); //isto não era necessário
  46. din.Print(); //chama um método existente na classe
  47. din.Action(); //chama o método que acabou de ser criado
  48. din.Clear(); //chama um método disponível no dicionário interno, mas que não está definido na classe
  49. din.Print(); //tá limpo
  50. din.NaoExiste(); //este método não existe
  51. dynamic exp = new ExpandoObject();
  52. exp.Action = new Action(() => WriteLine("Expando")); //só para mostrar que é possível fazer de forma automática, mas precisaria pesquisar
  53. exp.Action();
  54. }
  55. }
  56.  
  57. //https://pt.stackoverflow.com/q/137542/101
Success #stdin #stdout 0.26s 27072KB
stdin
Standard input is empty
stdout
Nome Walla
Sobrenome C#
Action Existe
Sem membros para listar
Executando método "NaoExiste".
Expando