2013-06-20 52 views
4

我有一個服務,有很多不同的方法與很多參數。我創建了一個服務客戶端,但爲所有可能的參數和函數創建UI將是一件非常痛苦的事情,因此每個方法只有一個按鈕,代碼將配置所有參數。它運行良好,但每次你需要另一個參數時,你都必須更改代碼。所以我認爲,如果我的文本框中包含將被編譯並且即時調用的代碼,那麼這將非常方便使用。所以我想要的是我有一個文本框,其代碼如ExecuteOperation1("a", "b", "c")其中ExecuteOperation在我的表單類中定義。然後我可以輕鬆地更改參數。我試圖搜索它是如何完成的,但是所有的例子都顯示了對命名空間和類的編譯等等。有沒有辦法在你的班級裏以某種方式運行動態代碼。我的問題的另一個簡單的解決方案,當然也讚賞。即時執行代碼從文本框

+0

你確定它是[tag:code-generation]而不是[tag:reflection]嗎? –

+0

檢查此鏈接http://www.codeproject.com/Articles/12499/Run-Time-Code-Generation-I-Compile-C-Code-using-Mi – Kurubaran

+0

@ J.A.I.L。不是很確定,也不是我想的,也許最好是刪除標籤。 –

回答

3

有幾種不同的運行代碼的方式。一個不錯的方法是使用Microsoft提供的文件dynamic.cs,可用here(在LinqSamples \ DynamicQuery \ DynamicQuery下)。使用示例是here

您還可以根據this article on MSDN自行手動構建表達式樹。但是你需要編寫一些解析代碼來完成這個任務。

我已經使用了上述兩種方法,並且我認爲第一種方法似乎是最有希望解決的問題。例如,您可以將任意對象o作爲表達式的參數,並且還包含其他對象,例如settings,因此用戶可以編寫o.ExecuteOperation1("a", "b", "c", settings),如下面的測試程序中所述。

using System.Linq.Expressions; 
using System.Linq.Dynamic; 

// ... 

public class Settings 
{ 
    public int x; 
} 

public class Window 
{ 
    public object ExecuteOperation1(string a, string b, string c, Settings s) 
    { 
     Console.WriteLine("{0}, {1}, {2}, {3}", a, b, c, s.x); 
     return true; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string strExpr = "o.ExecuteOperation1(\"a\", \"b\", \"c\", settings)"; 
     Window form = new Window(); 
     Settings s = new Settings(); 
     s.x = 42; 

     Type retType = typeof(object); 
     ParameterExpression[] paramExprs = new ParameterExpression[] { 
      Expression.Parameter(typeof(Window), "o"), 
      Expression.Parameter(typeof(Settings), "settings") }; 
     LambdaExpression Le = System.Linq.Dynamic.DynamicExpression.ParseLambda(
      paramExprs, retType, strExpr); 
     Delegate compiledLe = Le.Compile(); 

     object result = compiledLe.DynamicInvoke(form, s); 
     Console.WriteLine("Result is {0}", result.ToString()); 
    } 
} 

這個節目輸出

a, b, c, 42 
Result is True 

我有1137註釋掉線1138的Dynamic.cs來得到這個工作(這些行排除使用用戶定義類型Window的)。

最後,有Roslyn,它使得.net編譯器可以作爲服務使用。我自己並沒有使用過它,因爲它在技術預覽中,我想要現在可以部署的東西。儘管如此,它似乎有很多例子,有些適合你想要的那種東西。

+0

謝謝您的回答,我的參數實際上是我必須填寫的對象以及傳遞給方法的對象。因此,而不是隻是字符串「一」它必須是一個var設置=新的設置{\ *值設置在這裏* \}進一步傳遞給該方法。是否有可能寫入表達式? –

+0

我認爲你需要玩弄它看看你能做什麼。我可能會將設置對象定義在表單的一個單獨部分中,然後讓用戶將它們(它們)指定爲它們鍵入的字符串的一部分。我修改了我的答案以顯示它。 – TooTone

+0

最重要的部分是從文本框中獲得這個設置代碼,所以這不會像你的例子那樣工作。但我會試着看看我能否修改它來做我想做的事。也許我們可以用設置完成相同的技巧並將它們作爲單獨的表達式返回,但所有這些都會使這個事情變得非常複雜,我想只有一個包含所有操作代碼的文本框:創建對象參數,使用這些參數調用方法。 –

0

如果它總是看起來像ExecuteOperation1("a", "b", "c")那麼您可以使用反射來確定方法和參數名稱。例如,探索代碼給你一個方法列表。 MethodInfo.Invoke可以用來調用方法。

typeof(Service).GetMethods(BindingFlags.Public|BindingFlags.Instance); 

這種方法不是很靈活,但相對容易理解,不需要額外的庫。

+0

它不完全是「a」,「b」,「c」,它只是一個簡化不要詳細說明。我傳入了幾個複雜的對象參數,因此我不確定這樣可以使用它。對我來說最有趣的部分是正確填充這些對象的屬性 –