Det korte og nemme svar: Nej, det kan ikke lade sig gøre.
Det lange og besværlige svar: Tja, det kan helt sikkert gøres vha klasserne i System.Reflection.Emit namespacet. Disse klasser giver mulighed for dynamisk at opbygge CIL kode. Jeg har dog ikke nok kendskab til disse klasser til at kunne hjælpe dig.
Det tænkte jeg nok. Ja, dette eksempel var nok bedst løst med en switch. Jeg har blot før arbejdet med lignende opbygninger hvor det vil være kortere (men garanteret ikke bedre/mere effektivt) at bruge en dynamisk operator.
Tak for responsen, det besvarede mit spørgsmål :) Kunne jeg bede dig lægge et svar, så du også kan takkes elektronisk hehe.
Hvis du forhånd ved hvilken slags operator du vil bruge, vil jeg anbefale dig at undlade dynamiske operatorer.
Men hvis du absolut vil bruge dem, kan følgende måske bruges:
public int DynCalc(string oper, params[] int) { int result = params[0]; for(int i = 1; i < params.length; i++) { if (oper == "+") result += params[i]; else if (oper == "-") result -= params[i]; else if (oper == "*") result *= params[i]; else if (oper == "/") result /= params[i]; } return result; }
Tallene du vil have beregnet tilføjer du blot som: int mitTal = DynCalc("+", 1, 2, 3, 4, osv);
Tak for dit forslag mireigi, det var en ret smart måde at løse det på såfremt flere tal skulle kalkuleres. Længden virker dog ikke kortere og den virker også umiddelbart svære at læse. Men til mit problem, ville det nok fungere.
Jeg indrømmer gerne at den virker bøvlet ved mindre end 5-6 tal, men så snart du kommer over det, vil den være meget nemmere at bruge. Den kan sågar udbygges til at være fuldkomment dynamisk, men så bliver det lidt mere bøvlet.
Noget skummelt kode som er tæt relateret til problemet:
using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Reflection; using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace E { public interface IEval<TT> { TT Eval(TT[] args); } public class DynEval<T> { private static int n = 0; private static Regex re = new Regex(@"(\{)(\d+)(\})", RegexOptions.Compiled); private static Dictionary<string,IEval<T>> m = new Dictionary<string,IEval<T>>(); private static string KeyGen(string expr, string tn) { return expr + "#" + tn; } public static object Eval(string expr, params T[] args) { string tn = typeof(T).Name; IEval<T> o; if(m.ContainsKey(KeyGen(expr, tn))) { o = m[KeyGen(expr, tn)]; } else { n++; string cn = "C" + n; string expexpr = re.Replace(expr, "args[$2]"); string src = "using System;" + "using E;" + "" + "public class " + cn + " : IEval<" + tn + ">" + "{" + " public " + tn + " Eval(" + tn + "[] args)" + " {" + " return " + expexpr + ";" + " }" + "}"; CodeDomProvider comp = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters(); param.GenerateInMemory = true; param.ReferencedAssemblies.Add("System.dll"); param.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); CompilerResults res = comp.CompileAssemblyFromSource(param, src); Assembly asm = res.CompiledAssembly; o = (IEval<T>)asm.CreateInstance(cn); m.Add(KeyGen(expr, tn), o); } return o.Eval(args); } } public class MainClass { public static void Main(string[] args) { Console.WriteLine(DynEval<int>.Eval("{0}+{1}", 1, 2)); Console.WriteLine(DynEval<int>.Eval("{0}+{1}", 3, 4)); Console.WriteLine(DynEval<int>.Eval("({0}*{1}+{2})/{3}", 5, 4, 1, 2)); Console.WriteLine(DynEval<double>.Eval("{0}+{1}", 1.2, 3.4)); Console.WriteLine(DynEval<string>.Eval("{0}+{1}", "AB", "CD")); } } }
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.