2010-01-21 22 views
5

Có thể viết một hàm đơn giản và nhanh chóng trong C# để thực hiện các phương thức tùy ý từ một chuỗi không? Ví dụ, nếu tôi đặt MyString = "MessageBox.Show (" Some Message ")" và sau đó gọi ExecuteString (MyString), một hộp thông báo sẽ bật lên với "Some Message" trong đó.C#: thực hiện một chức năng được lưu trữ trong một biến chuỗi

(tôi đã có thể thực hiện một số loại lỗi trong đoạn mã trên tôi chưa biết C#;. Tôi đang cố gắng để đánh giá liệu nó sẽ là thích hợp cho một dự án cụ thể.)

+2

Không chắc nếu điều này là một bản sao, nhưng bạn có thể tìm kiếm một cách để đến repl trong C#, và có một câu hỏi hay về điều đó ở đây: http://stackoverflow.com/questions/1038106/ hoặc tại đây http://stackoverflow.com/questions/2058715/ có thể cung cấp một số ý tưởng/mã nguồn. –

Trả lời

2

Than ôi, C# không phải là ngôn ngữ động theo cách đó. Bạn không thể thực sự làm điều này một cách dễ dàng, và nếu nó thực sự là một cái gì đó bạn cần làm, hãy xem xét sử dụng một ngôn ngữ Net hơn phù hợp với nhu cầu của bạn, như IronPython hoặc IronRuby.

thay thế có sẵn tốt nhất của bạn là sử dụng không gian tên CodeDOM, làm ví dụ thực sự phức tạp và ghê tởm này từ this forum thread show:

using System; 
using System.CodeDom; 
using System.CodeDom.Compiler; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.Linq; 
using System.Reflection; 
using System.Reflection.Emit; 
using System.Text; 
using System.Windows.Forms; 

namespace TestApp 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     SampleLib.SampleType test = new SampleLib.SampleType(); 

     private void button1_Click(object sender, EventArgs e) 
     { 
      // Dynamically build and call the method 
      label1.Text = test.MyText; 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      StringBuilder DynamicCode = new StringBuilder(); 
      DynamicCode.Append("namespace TestDynamic"); 
      DynamicCode.Append("{"); 
      DynamicCode.Append("public class DynamicCode"); 
      DynamicCode.Append("{"); 
      DynamicCode.Append("public static void EditText(SampleLib.SampleType t)"); 
      DynamicCode.Append("{"); 
      DynamicCode.Append("t.MyText = \"Goodbye!\";"); 
      DynamicCode.Append("}"); 
      DynamicCode.Append("}"); 
      DynamicCode.Append("}"); 

      string CodeString = DynamicCode.ToString(); 

      System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath); 
      CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); 
      CompilerParameters CompileParams = new CompilerParameters(new string[] { fi.DirectoryName + "\\SampleLib.dll" }, 
       fi.DirectoryName + "\\Dynamic.dll"); 
      CompileParams.MainClass = "DynamicCode"; 
      CompileParams.GenerateExecutable = false; 
      //CompileParams.GenerateInMemory = true; 
      CompilerResults r = provider.CompileAssemblyFromSource(CompileParams, new string[] {CodeString}); 
      foreach (CompilerError er in r.Errors) 
      { 
       Console.WriteLine(er.ErrorText); 
      } 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      // Dynamically call assembly 
      System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath); 
      Assembly dynAsm = Assembly.LoadFile(fi.DirectoryName + "\\Dynamic.dll"); 
      if (dynAsm != null) 
      { 
       object o = dynAsm.CreateInstance("TestDynamic.DynamicCode", true); 
       Type t = dynAsm.GetType("TestDynamic.DynamicCode"); 
       t.GetMethod("EditText").Invoke(o, new object[]{test}); 
      } 
     } 
    } 
} 
+0

Bạn thực sự có thể. Tôi không chỉ đăng tải như thế nào, mà còn tự mình làm. –

+1

Tôi không nói nó không phải là _possible_, chỉ là nó không phải là _easy_. Tôi không chắc chắn rằng ví dụ MSDN bạn đề cập đến - đòi hỏi hơn 100 dòng để "thực hiện" một dòng mã, hãy nhớ bạn - có thể được coi là dễ dàng. –

3

Bạn sẽ có thể sử dụng điều này và quấn mã cần thiết để chạy một chuỗi thành một hàm. Về cơ bản những gì bạn đang làm là gói một chút mã C# trong một chức năng kiểu Program.Main, tham khảo một số hội đồng cho chức năng cơ bản (có thể bao gồm lắp ráp của riêng bạn), sau đó chạy chương trình đã biên dịch trong bộ nhớ.

Có thể có nhiều chi phí hơn bạn cần chỉ cần chạy một hoặc hai dòng mã bạn.

http://support.microsoft.com/kb/304655

+0

Đồng ý - giải pháp thay thế tốt nhất thực sự là ủy thác loại công việc này cho IronPython hoặc IronRuby, nơi dễ thực hiện hơn nhiều. –

+0

Vâng, sẽ tốt hơn nếu sử dụng các phương pháp dựa trên kịch bản nhẹ cho một lượng nhỏ "mã kịch bản" như vậy. –

+0

Nếu bối cảnh được yêu cầu, ví dụ truy cập vào biến thời gian và các lớp trong ứng dụng máy chủ từ chuỗi mã hơn ironPython hoặc các ngôn ngữ DLR khác tốt hơn nhiều hoặc nếu chuỗi mã thay đổi thường xuyên hơn việc biên dịch không phải là một lựa chọn tốt như bạn sẽ tạo lắp ráp cho mỗi chuỗi mã cần đánh giá. – affan

Các vấn đề liên quan