有两个方法public class MyTem
    {
        public MyTem() { }
        public static int GetA()
        {
            return 1;
        }        public static int GetB()
        {
            return 2;
        }
    }现在已知字符串:"GetA()+GetB()"C#代码如何可以执行成:int i=GetA()+GetB()------------------------------------------------------------------
当然,不仅是以上定义,还要能解决同类问题,比如ABS(GetA()+5)-GetB()等等也看过CodeDOM,但理解不深,不过不知道能不能解决这个问题。
请各路高手多多援助!

解决方案 »

  1.   

     int i=MyTem.GetA()+MyTem.GetB(); 其他类似,但都要定义成静态的. public static int ABS() 
     
     
      

  2.   

    楼上,不是这个意思。是通过字符串“GetA()+GetB()”后,执行GetA()+GetB(),也就是说像C++的宏一样的东东。
      

  3.   

    CodeDOM可以解决这样的问题,只要你能写出一个这样的程序问题就解决了。
      

  4.   

    CodeMemberMethod GetMethod = new CodeMemberMethod();GetMethod.Comments.Add(new CodeCommentStatement("GetFunction"));
    GetMethod.Name = "GetFunction";//方法名 
    GetMethod.Attributes = MemberAttributes.Public;//可见性 
    GetMethod.Parameters.Add(......);//参数
    ......==========================================================
    hbxtlhx ,能帮写几行例子吗?
      

  5.   

    你只能
    把整个“public class MyTem 
        { 
            public MyTem() { } 
            public static int GetA() 
            { 
                return 1; 
            }         public static int GetB() 
            { 
                return 2; 
            }
            
            public static int GetValue()
            {
                return GetA()+GetB();
            } 
        }”当成字符串,然后即时编译,调用GetValue方法得到返回值
      

  6.   

    那就提供一部分动态编译的代码吧,仅供参考,对楼主问题可能有用:
    private List<string> m_using = new List<string>();
    public frmMain()
    {
    InitializeComponent();
    m_using.Add("System.dll");
    } public static bool CompileCSharpCode(List<string> usings, string source, TextBox outputBox)
    {
    CSharpCodeProvider provider = new CSharpCodeProvider();
    CompilerParameters cp = new CompilerParameters();
    foreach (string us in usings)
    {
    cp.ReferencedAssemblies.Add(us);
    }
    cp.GenerateExecutable = false;
    cp.OutputAssembly = null;
    cp.GenerateInMemory = true; CompilerResults cr = provider.CompileAssemblyFromSource(cp, source);
    if (cr.Errors.Count > 0)
    {
    outputBox.Text += string.Format("Errors building \r\n{0}", source);
    outputBox.Text += "\r\n"; foreach (CompilerError ce in cr.Errors)
    {
    outputBox.Text += "(" + ce.ErrorNumber + ")" + ce.ErrorText;
    outputBox.Text += "\r\n";
    } }
    else
    {
    outputBox.Text += "built successfully.\r\n";
    } if (cr.Errors.Count > 0)
    {
    return false;
    }
    else
    {
    try
    {
    outputBox.Text += StartRun(cr.CompiledAssembly);
    outputBox.Text += "\r\n";
    }
    catch (Exception ex)
    {
    outputBox.Text += ex.Message;
    outputBox.Text += "\r\n";
    }
    return true;
    }
    } private static string StartRun(Assembly assembly)
    {
    Type[] types = assembly.GetTypes();
    if (types != null && types.Length > 0)
    {
    Type type = types[0];
    if (type != null)
    {
    object obj = assembly.CreateInstance(type.FullName);
    MethodInfo mi = type.GetMethod("main", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    if (mi != null)
    {
    object tmpRet = mi.Invoke(obj, null);
    if (tmpRet != null)
    {
    return tmpRet.ToString();
    }
    }
    }
    }
    return null;
    } private void tbnRun_Click(object sender, EventArgs e)
    {
    this.txtOutput.Clear();
    CompileCSharpCode(this.m_using, this.txtCode.Text, this.txtOutput);
    }
      

  7.   

    参考一下http://www.chenjiliang.com/Article/View.aspx?ArticleID=2767&TypeID=84
      

  8.   

    CodeDOM 速度很慢, 建议自行解释字符串取得方法列表后利用反射调用...
      

  9.   

    lovefootball: 参考的方法不可取,GetA()和GetB()等等这些方法都是C#类里的,都是运行在后台的。shinaterry : 我有这种担心,而且也不知道在多用户的情况下,编译和生成是否有问题。
      

  10.   

    hbxtlhx ,请教:using System;
    using System.Collections.Generic;
    using System.Text;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;namespace WindowsApplication1
    {
        public class Eval
        {
            public static object GetValue( string value )
            {
                string codeSnippet = "using System; " + "\r\n" +
                                                "namespace CzG {" + "\r\n" +
                                                            " public class Eval" + "\r\n" +
                                                            " {" + "\r\n" +
                                                "       public Eval(){} " + "\r\n" +
                                                            "  public object GetValue()" + "\r\n" +
                                                            "  {" + "\r\n" +
                                                            "   return " + value + ";" + "\r\n" +
                                                            "  }" + "\r\n" +
                                                            " } }";            CodeSnippetCompileUnit unit = new CodeSnippetCompileUnit( codeSnippet ); 
             
               ICodeCompiler compiler =  new CSharpCodeProvider().CreateCompiler();
               CompilerParameters para = new CompilerParameters();
               para.ReferencedAssemblies.Add( "System.dll" );
               para.GenerateInMemory = true;
               para.GenerateExecutable = false;
               para.OutputAssembly = "Eval.dll";
               
               Assembly asm = compiler.CompileAssemblyFromDom( para , unit ).CompiledAssembly;           Type type = asm.GetType("CzG.Eval");
               MethodInfo mi = type.GetMethod( "GetValue" , BindingFlags.Public | BindingFlags.Instance );           object obj = asm.CreateInstance("CzG.Eval");
               return mi.Invoke( obj , null );
              }        public static string GetA() { return "A"; }
            public static string GetB() { return "B"; }
        }
    }private void button2_Click(object sender, EventArgs e)
            {
                string s1 = Convert.ToString(Eval.GetValue("(5 + 6*3)-10"));
                //string s2 = Convert.ToString(Eval.GetValue("WindowsApplication1.GetA()"));
    }========================================================
    以上代码可得到s1,但想得到s2是提示编译错误,如何解决?
      

  11.   

    修改如下:using System;
    using System.Collections.Generic;
    using System.Text;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;namespace WindowsApplication1
    {
        public class Demo
        {
            public static object GetValue(string value)
            {
                string codeSnippet = "using System;" + "\r\n" +
                                     "using " + typeof(Demo).Namespace + ";" + "\r\n" +
                                                "namespace CzG {" + "\r\n" +
                                                            " public class Eval" + "\r\n" +
                                                            " {" + "\r\n" +
                                                "       public Eval(){} " + "\r\n" +
                                                            "  public object GetValue()" + "\r\n" +
                                                            "  {" + "\r\n" +
                                                            "   return " + value + ";" + "\r\n" +
                                                            "  }" + "\r\n" +
                                                            " } }";            CodeSnippetCompileUnit unit = new CodeSnippetCompileUnit(codeSnippet);            ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
                String[] referenceAssemblies = { typeof(Demo).Module.FullyQualifiedName, "System.dll" };
                CompilerParameters para = new CompilerParameters(referenceAssemblies);
                para.GenerateInMemory = true;
                para.GenerateExecutable = false;
                para.OutputAssembly = "Eval.dll";            Assembly asm = compiler.CompileAssemblyFromDom(para, unit).CompiledAssembly;            Type type = asm.GetType("CzG.Eval");
                MethodInfo mi = type.GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance);            object obj = asm.CreateInstance("CzG.Eval");
                return mi.Invoke(obj, null);
            }        public static string GetA() { return "A"; }
            public static string GetB() { return "B"; }
        }
    }测试代码:private void button2_Click(object sender, EventArgs e)
    {
        string s1 = Convert.ToString(Eval.GetValue("(5 + 6*3)-10"));
        string s2 = Convert.ToString(Eval.GetValue("WindowsApplication1.Demo.GetA()"));
    }
      

  12.   

    ref: 编译和生成是否有问题。
    ---------
    ^ō^ 那就视乎你的服务器的承受能力...
      

  13.   

    简单求值运算我一般都用Script对象直接Eval得出
      

  14.   

    Eval.Cs单元
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;namespace WindowsApplication1
    {
        public class Demo
        {
            public static object GetValue(string value)
            {
                string codeSnippet = "using System;" + "\r\n" +
                                     "using " + typeof(Demo).Namespace + ";" + "\r\n" +
                                                "namespace CzG {" + "\r\n" +
                                                            " public class Eval" + "\r\n" +
                                                            " {" + "\r\n" +
                                                "       public Eval(){} " + "\r\n" +
                                                            "  public object GetValue()" + "\r\n" +
                                                            "  {" + "\r\n" +
                                                            "   return " + value + ";" + "\r\n" +
                                                            "  }" + "\r\n" +
                                                            " } }";            CodeSnippetCompileUnit unit = new CodeSnippetCompileUnit(codeSnippet);            ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
                String[] referenceAssemblies = { typeof(Demo).Module.FullyQualifiedName, "System.dll" };
                CompilerParameters para = new CompilerParameters(referenceAssemblies);
                para.GenerateInMemory = true;
                para.GenerateExecutable = false;
                para.OutputAssembly = "Eval.dll";            Assembly asm = compiler.CompileAssemblyFromDom(para, unit).CompiledAssembly;            Type type = asm.GetType("CzG.Eval");
                MethodInfo mi = type.GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance);            object obj = asm.CreateInstance("CzG.Eval");
                return mi.Invoke(obj, null);
            }        public static string GetA() { return "A"; }
            public static string GetB() { return "B"; }
        }}
    调用测试代码:
    private void button2_Click(object sender, EventArgs e)
            {
                string s = Convert.ToString(Demo.GetValue("WindowsApplication1.Demo.GetA()+WindowsApplication1.Demo.GetB()"));
                txtOutput.Text = s;
            }================================
    shinaterry 的代码是可以的。