Avatar billede c3-rp Nybegynder
08. december 2008 - 12:01 Der er 7 kommentarer og
1 løsning

Bruge string variabel som operator

Jeg er næsten klar over det ikke er muligt, men bliver alligevel nødt til at være sikker.

Hvis man ser bort fra fejlhåndtering og generel kode-etik, kan følgende så lade sig gøre?

int number1;
int number2;
string oper = "+";
result = number1 oper= number2;

.. hvis man caster oper til en operator på en eller anden måde?
Avatar billede aaberg Nybegynder
08. december 2008 - 12:41 #1
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.
Avatar billede aaberg Nybegynder
08. december 2008 - 12:45 #2
I dit tilfælde ville det nok være nemmere at lave en metode som kan håndtere det.

public int DynamicOperator(int number1, int number2, string operator)
{
  switch(operator)
  {
      case "+":
        return number1 += number2;
        break;
      case "-":
        return number1 -= number2;
        break
      osv....
  }
}
Avatar billede c3-rp Nybegynder
08. december 2008 - 12:50 #3
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.
Avatar billede aaberg Nybegynder
08. december 2008 - 12:58 #4
:-D
Avatar billede mireigi Novice
08. december 2008 - 13:00 #5
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);
Avatar billede c3-rp Nybegynder
08. december 2008 - 13:08 #6
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.
Avatar billede mireigi Novice
08. december 2008 - 13:25 #7
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.
Avatar billede arne_v Ekspert
21. december 2008 - 05:18 #8
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"));
        }
    }
}
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester