2012-11-18 107 views
1

好的,請不要爲了這個問題而讓我失望。C#將參數化方法的名稱傳遞給變量

// using System.Threading;

private void startThread() 
    {    
     Thread t = new Thread(ParameterizedThreadStart(setOutputBinaryWorker)); 
     t.Start(); 
    } 

由於setOutputBinaryWorker是一個實際的現有方法,所以此工作正常。不過,我正在尋找一種方法將函數名稱作爲變量傳遞給startThread函數。

感謝我有限的C#經驗,我懷疑它有可能,但似乎無法弄清楚如何。我可以想像它應該是這樣的:

// using System.Threading; 

    private void startThread(??datatype?? func) 
    {    
     Thread t = new Thread(ParameterizedThreadStart(func)); 
     t.Start(); 
    } 

但我找不出數據類型應該是什麼(使用問號)。 現在,在調試時,傳遞函數名會彈出

System.Object的虛空,setOutputBinaryWorker

它只是不給我太多去。可以創建這些嗎?嘗試將參數作爲(對象)不起作用。

背後的主要想法是試驗一個安全的gui線程以正確的方式寫入UI元素。 現在,我已經得到了這部分,使用委託方法,它只是花花公子。但是,切換到當前的方法(使方法名稱變量),我完全失去了。 如果有人知道替代方案,更好,或至少是工作解決方案,我願意接受建議,時間很長。

在此先感謝您的努力。

+1

你爲什麼不傳遞一個ParameterizedThreadStart?另外:對於ParameterizedThreadStart版本,您是否需要將值傳遞給Start? –

+0

感謝您的快速回復,是的,我確實。在迴應你的問題:這將無法正常工作,我需要傳遞函數名稱,因爲它將被包裝在外部DLL中。 – Digitalis

+0

你會用這種方式調用什麼樣的方法?他們是否具有相同的簽名和返回值? –

回答

2

數據類型應與簽名的委託:

無效(對象) - 這意味着,不返回任何東西,需要對象參數的方法

例子:

delegate void TestDelegate(object o); 

     private void button4_Click(object sender, EventArgs e) 
     { 
      TestDelegate custom = SomeMethod; 
      ParameterizedThreadStart pts = new ParameterizedThreadStart(custom); 
      Thread thread = new Thread(pts); 
      thread.Start(); 
     } 

     private void SomeMethod(object o) 
     { 
      MessageBox.Show("Hey!"); 
     } 

注意,我們傳遞AV可變的TestDelegate類型。這使您可以在運行時將不同的方法傳遞給線程,只要這些方法符合委託簽名。

配對反思:

// assuming class is in same assembly as this method 
    Assembly assembly = Assembly.GetExecutingAssembly(); 
    // you can choose to get type from an known object instead 
    Type type = assembly.GetType("Test.SomeClass"); 
    object instance = Activator.CreateInstance(type, null);    
    MethodInfo methodInfo = type.GetMethod("SomeMethod");       
    object[] parameterValues = new object[] { 1 };    
    methodInfo.Invoke(instance, parameterValues); 

使用反射時,只是要留意的性能。如果可以,請緩存創建的對象,以避免使用「反射」創建對象。

+0

感謝您的回覆。我確實瞭解委託數據類型。然而,如果我錯了,請糾正我,但SomeMethod仍然必須是現有的功能。練習的要點是消除這一點。我想設置該函數,以便可以將另一個類中定義的委託方法傳遞給它,以便與parameterizedThreadStart一起使用。 – Digitalis

+0

比較。 PHP允許函數名作爲字符串傳遞。因此,完全取決於您如何以及在何處定義函數。在C#中可能類似的事情嗎?或者它只是沒有做到這一點? – Digitalis

+0

反射是否符合您的要求?我更新了我的答案以包含Reflection。 – rro

1

我會用lambda表達式

Thread t =new Thread(
() => 
    { 
    function(anyparameter); 
    } 
).Start(); 
+0

好的,我很感興趣,但是這到底做了什麼?它以哪種方式取代我的代碼? – Digitalis

+0

@Digitalis而不是使用ParameterizedThreadStart,你可以通過參數 –

+0

好吧。我很抱歉,我相信這是高於我的薪酬級別。你是說我原來要求的選擇是不可能的?或者這只是更快/更好/更新? – Digitalis