我想讓用戶寫一段代碼作爲文本,在飛行中編譯它,在我從數據源獲得的集合上執行它並獲得結果。如何將通用列表傳遞給動態編譯的C#代碼?
我一直在綁定將通用列表作爲參數傳遞給動態編譯的代碼,但我找不到一種方法。以下是我的代碼:
//User writes this code in a textbox and executes
var executeCode = @"//this line doesn't work because I don't know the type
MessageBox.Show(Parameters[0].Count());
//following works fine
var t = new List<string>{""asd"", ""xyz""};
var a = t.Select(x => x).First();
MessageBox.Show(a);
return (object) a;";
#region template Code
executeCode = @"
using System;
using System.IO;
using System.Windows.Forms;
using System.Linq;
using System.Collections.Generic;
namespace MyNamespace {
public class MyClass {
public object DynamicCode(params object[] Parameters) {
" + executeCode +
"} } }";
#endregion template Code
var references = new[] { "System.dll", "System.Core.dll", "System.Windows.Forms.dll" };
var compilerParams = new CompilerParameters
{
GenerateInMemory = true,
TreatWarningsAsErrors = false,
GenerateExecutable = false,
CompilerOptions = "/optimize"
};
compilerParams.ReferencedAssemblies.AddRange(references);
var provider = new CSharpCodeProvider();
var compile = provider.CompileAssemblyFromSource(compilerParams, executeCode);
if (compile.Errors.HasErrors)
{
var text = compile.Errors.Cast<CompilerError>()
.Aggregate("Compile Error: ", (current, ce) => current + ("rn" + ce.ToString()));
throw new Exception(text);
}
// execute the compiled code
var assembly = compile.CompiledAssembly;
var myObject = assembly.CreateInstance("MyNamespace.MyClass");
if (myObject == null)
{
MessageBox.Show("Couldn't load class.");
return;
}
var sampleList = new List<string> { "abcd", "bcd" };
var codeParams = new object[] { sampleList };
try
{
var loResult = myObject.GetType().InvokeMember("DynamicCode",BindingFlags.InvokeMethod, null, myObject, codeParams);
MessageBox.Show("Method Call Result:\r\n\r\n" + loResult, "Compiler Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception loError)
{
MessageBox.Show(loError.Message, "Compiler Demo", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
在上面的代碼,我傳遞一個字符串列表。但是我會用一個對象替換它。用戶將編寫Linq查詢來過濾集合,我即時編譯並返回結果。
對此的任何指針都會非常有幫助。 (我使用C#4.5)
你真的不得不以這種難以管理的方式編碼嗎?有一種叫做「接口」的東西,它是幾十年前發明的。 – zsong
@sza這是我的臨時代碼。我將修復可管理性部分,如果它達到目的......否則爲什麼要刮更多代碼? – Amit
你正試圖調用'.Count()',這樣你就可以立刻向下向'IEnumerable