codice:
namespace Test
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
Dictionary<string, string> dizionario = new Dictionary<string, string>();
dizionario.Add("professione", "Sono un developer!");
APearson Developer = EstendiAstratta("pippo ", "paperino", "Developer", "Test", dizionario, "public override string GetFullName() { return Name+Surname; }");
MessageBox.Show(Developer.GetFullName());
APearson Developer2 = EstendiAstratta("pippo ", "paperino", "Developer2", "Test", dizionario, "public override string GetFullName() { return professione; }");
MessageBox.Show(Developer2.GetFullName());
dizionario["professione"] = "Sono un Architect";
APearson Architect = EstendiAstratta("pippo ", "paperino", "Architect", "Test", dizionario, "public override string GetFullName() { return Name+Surname; }");
MessageBox.Show(Architect.GetFullName());
APearson Architect2 = EstendiAstratta("pippo ", "paperino", "Architect2", "Test", dizionario, "public override string GetFullName() { return professione; }");
MessageBox.Show(Architect2.GetFullName());
}
public static APearson EstendiAstratta(string name, string surname, string nomeClasse, string nameSpace, Dictionary<string, string> proprieta, string voidGetFullName)
{
CSharpCodeProvider CSharpCodeProvider = new CSharpCodeProvider();
ICodeCompiler Compilatore = CSharpCodeProvider.CreateCompiler();
CompilerParameters ParametriCompilatore = new CompilerParameters();
ParametriCompilatore.GenerateInMemory = true;
ParametriCompilatore.IncludeDebugInformation = true;
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
ParametriCompilatore.ReferencedAssemblies.Add(asm.Location);
}
catch
{
return null;
}
}
StringBuilder CodiceSorgente = new StringBuilder();
CodiceSorgente.Append("using System;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("using System.Collections.Generic;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("using Test;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("using System.Text;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("using Microsoft.CSharp;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("using System.CodeDom.Compiler;");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("namespace "); CodiceSorgente.Append(nameSpace);
CodiceSorgente.Append("\n");
CodiceSorgente.Append("{\n");
CodiceSorgente.Append("public class "); CodiceSorgente.Append(nomeClasse);
CodiceSorgente.Append(" : "); CodiceSorgente.Append(typeof(APearson));
CodiceSorgente.Append("\n");
CodiceSorgente.Append("{\n");
foreach (string nomeProprieta in proprieta.Keys)
{
string nomeProprietaMaiuscola = nomeProprieta.Substring(0, 1).ToUpper() + nomeProprieta.Substring(1, nomeProprieta.Length - 1);
string minuscola = nomeProprieta.Substring(0, 1).ToLower() + nomeProprieta.Substring(1, nomeProprieta.Length - 1);
CodiceSorgente.Append("public string "); CodiceSorgente.Append(nomeProprietaMaiuscola);
CodiceSorgente.Append("{ get{ return " + minuscola + ";} set{ " + minuscola + " = value; }}"); CodiceSorgente.Append("\n");
CodiceSorgente.Append("\n");
CodiceSorgente.Append("string ");
CodiceSorgente.Append(minuscola); CodiceSorgente.Append(" = ");
CodiceSorgente.Append(@""""); CodiceSorgente.Append(proprieta[nomeProprieta]); CodiceSorgente.Append(@"""");
CodiceSorgente.Append(";");
}
CodiceSorgente.Append("public "); CodiceSorgente.Append(nomeClasse); CodiceSorgente.Append("(string name, string surname) : base(name,surname){}");
CodiceSorgente.Append(voidGetFullName);
CodiceSorgente.Append("\n}}");
CompilerResults RisultatoCompilatore = Compilatore.CompileAssemblyFromSource(ParametriCompilatore, CodiceSorgente.ToString());
if (RisultatoCompilatore.Errors.HasErrors)
{
foreach (CompilerError Errore in RisultatoCompilatore.Errors)
{
if (!Errore.IsWarning)
{
return null;
}
}
}
Type t = null;
for (int i = 0; i < RisultatoCompilatore.CompiledAssembly.GetTypes().Length; i++)
{
if (RisultatoCompilatore.CompiledAssembly.GetTypes()[i].Name == nomeClasse)
{
t = RisultatoCompilatore.CompiledAssembly.GetTypes()[i];
break;
}
}
return (APearson)t.InvokeMember(nomeClasse, System.Reflection.BindingFlags.CreateInstance, null, null, new object[] { name, surname });
}
}
public interface IPearson
{
string Name { get; set; }
string Surname { get; set; }
string GetFullName();
}
public abstract class APearson : IPearson
{
public string Name { get; set; }
public string Surname { get; set; }
public APearson(string name, string surname)
{
this.Name = name;
this.Surname = surname;
}
public abstract string GetFullName();
}
}
ovviamente è buttata giù al volo, e sostanzialmente si tratta di usare