Ciao
potresti sfruttare la possibilità di creare assembly al volo: il procedimento consiste nel creare una classe che compili in runtime nella quale dichiari la funzione inserita nella textbox. Poi utilizzi l'assembly creato per chiamare la funzione tramite reflection, e ottieni il risultato del calcolo.
Ti scrivo un esempio banale per farti capire:
//Questa funzione crea il calcolatore passando come argomento
//Il testo della funzione
public object CreateFunctionCalculator(string function)
{
Microsoft.CSharp.CSharpCodeProvider provider =
new Microsoft.CSharp.CSharpCodeProvider();
CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = true;
param.GenerateExecutable = false;
param.ReferencedAssemblies.Add("System.dll");
string tempClass = "using System; " +
"class Calculator{" +
"public object Calculate(double x) {" +
"return " + function + " ;" +
"} } ";
CompilerResults results =
provider.CompileAssemblyFromSource(param, tempClass);
if (results.Errors.HasErrors)
{
throw new ArgumentException("Funzione inserita non valida");
}
return results.CompiledAssembly.CreateInstance("Calculator");
}
//Questa funzione calcola il risultato a partire
//dal calcolatore creato con la funzione precedente
//e il valore della variabile
public object Calculate(object calculator, double x)
{
MethodInfo method = calculator.GetType().GetMethod("Calculate");
if (method == null)
{
throw new ArgumentException("Metodo non definito");
}
return method.Invoke(calculator, new object[] { x });
}
Un esempio di come usarlo potrebbe essere il seguente:
{
object calc = CreateFunctionCalculator("(x+2)*(x-6)/x");
object result = Calculate(calc, 12);
MessageBox.Show(result.ToString());
}
E come risultato dovrebbe dare 7. Sostituendo all'espressione il valore della textbox ottieni il tuo calcolatore di funzioni.
Naturalmente per funzioni più complesse (come logaritmi, trigonometriche ecc...) devi scegliere fra le seguenti:
- O scrivi un testo contenente una classe parziale dove definisci le funzioni che ti interessano, e rendi parziale anche la classe temporanea che compili, avendo così a disposizione tutte le funzioni che ti servono;
- Oppure fai una sostituzione di ogni occorrenza della funzione con "Math.Funzione"
Luca