有两个方法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,但理解不深,不过不知道能不能解决这个问题。
请各路高手多多援助!
{
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,但理解不深,不过不知道能不能解决这个问题。
请各路高手多多援助!
GetMethod.Name = "GetFunction";//方法名
GetMethod.Attributes = MemberAttributes.Public;//可见性
GetMethod.Parameters.Add(......);//参数
......==========================================================
hbxtlhx ,能帮写几行例子吗?
把整个“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方法得到返回值
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);
}
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是提示编译错误,如何解决?
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()"));
}
---------
^ō^ 那就视乎你的服务器的承受能力...
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 的代码是可以的。