我有一個公共類「CodeCompiler」,它允許我在運行時編譯和運行C#代碼。就像IDE一樣工作。「非靜態字段,方法或屬性需要對象引用。」同時在運行時編譯C#代碼
當我點擊「button1」它在運行時創建代碼,編譯並執行。
我的主Form1包含一個名爲「textbox1」的TextBox控件。爲了通過運行時對「textbox1」進行更改,我製作了這個button1_Click事件。 但是,當我點擊它,它讓我看到一個運行時錯誤...
Compiler Errors :
Line 14,34 : An object reference is required for the non-static field, method, or property 'Compiling_CSharp_Code_at_Runtime.Form1.textBox1'
這表明我當我編輯對「TextBox1的」文本數據。但是,如果我將嘗試對「大小」,「位置」等其他屬性進行更改,那麼想象會發生什麼!
using System;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace Compiling_CSharp_Code_at_Runtime
{
public class CodeCompiler
{
public CodeCompiler()
{
}
public object ExecuteCode(string code, string namespacename, string classname,
string functionname, bool isstatic,
string[] References1, params object[] args)
{
object returnval = null;
CompilerParameters compilerparams = new CompilerParameters();
for (int i = 0; i <= References1.GetUpperBound(0); i++)
{
compilerparams.ReferencedAssemblies.Add(References1[i]);
}
Assembly asm = BuildAssembly(code, compilerparams);
object instance = null;
Type type = null;
if (isstatic)
{
type = asm.GetType(namespacename + "." + classname);
}
else
{
instance = asm.CreateInstance(namespacename + "." + classname);
type = instance.GetType();
}
MethodInfo method = type.GetMethod(functionname);
returnval = method.Invoke(instance, args);
return returnval;
}
private Assembly BuildAssembly(string code, CompilerParameters compilerparams)
{
Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
CompilerResults results = compiler.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
return results.CompiledAssembly;
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CodeCompiler cc = new CodeCompiler();
string SourceCode1 = @"
using Compiling_CSharp_Code_at_Runtime;
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
namespace N1
{
public class C1
{
public static void F1(string st1, string st2)
{
Compiling_CSharp_Code_at_Runtime.Form1.textBox1.Text += ""This is a DEMO "" st1 + st2.ToUpper();
}
}
}";
string namespace1 = "N1", class1 = "C1", function1 = "F1";
bool IsStatic = true;
object o = cc.ExecuteCode(SourceCode1, namespace1, class1, function1, IsStatic, new string[] { "Compiling CSharp Code at Runtime.exe", "System.Windows.Forms.dll", "System.Drawing.dll", "System.ComponentModel.dll", "System.dll" }, "arg1", "arg2");
}
}
}
我發現與此相關的問題,在這個網站,其中一個建議是很多問題:
「它看起來像我打電話從一個靜態方法非靜態屬性 我應該要麼使財產靜態,或創建Form1的實例。「
但即使創建Form1的實例在運行時也很困難!
這將工作,如果我會使該textbox1作爲一個公共和靜態!但是...... – IremadzeArchil19910311 2014-11-01 15:54:31
那麼你如何期待它得到正確的實例呢?爲什麼不將形式引用傳遞給方法,或者類似的東西? – 2014-11-01 15:59:30
C1類不是靜態的,這意味着你必須在使用它之前對它進行初始化。它確實有一個靜態方法,可以調用,但是任何嘗試使用沒有Initing的C1都會失敗。 – 2014-11-01 16:03:28