2016-04-20 37 views
0

在C#中可以有一個方法接受一個委託,有零,1或許多參數?C#lamba作爲參數的方法

在下面的方法中,當我在對話框中單擊「是」時,我希望能夠做某種事情。我爲此使用了一個委託,但目前它只接受不帶參數的方法。

有可能有多種方法來做到這一點,如傳遞一個包含參數的泛型類,但是最好的方法是什麼? C#是否提供了一些開箱即用的方式以優雅的方式來完成此操作?

public static bool ShowCustomDialog(string message, 
             string caption, 
             MessageBoxButtons buttons, 
             XafApplication application, 
             Action onYes = null) 
    { 
     Messaging messageBox = new Messaging(application); 
     var dialogResult = messageBox.GetUserChoice(message, caption, buttons); 
     switch (dialogResult) 
     { 
      case DialogResult.Yes: 
       onYes?.Invoke(); 
       break; 
     } 
     return false; 
    } 
+0

沒有,這是不可能創建accespts的參數的任何任意數目的FUNC如'行動','ActionT1,T2,...>'的方法。 – HimBromBeere

回答

4

直接解決你的問題,這就是爲什麼你使用lambda表達式:

ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo, 
       () => DoSomething(myArgument, anotherArgument)); 

這是在像依賴注入技術的核心 - ShowCustomDialog方法應該不知道有這個動作任何東西,除了事實上它不需要輸入ShowCustomDialog方法本身。如果ShowCustomDialog必須通過一些參數,則可以使用Action<SomeType>而不是Action

在封面下,編譯器創建一個包含要傳遞的參數的類,並創建一個代表該類的實例。因此,它是(主要是),相當於手工編寫這樣的事:

class HelperForTwoArguments 
{ 
    bool arg1; 
    string arg2; 

    public HelperForTwoArguments(bool arg1, string arg2) 
    { 
    this.arg1 = arg1; 
    this.arg2 = arg2; 
    } 

    public void Invoke() 
    { 
    DoSomething(arg1, arg2); 
    } 
} 

// ... 

ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo, 
       new HelperForTwoArguments(myArgument, anotherArgument).Invoke); 

這種能力一直在從一開始的.NET框架,它只是得到了更容易使用與匿名委託和lambda表達式特別。

但是,我不得不說我根本沒有看到任何指向你的「幫手」的方法。與做這樣的事情有什麼不同?

if (ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo)) 
    DoSomething(myArgument, anotherArgument); 
+0

我猜OP需要通過任意任意數量的參數,而不是隻有一個。所以這也應該爲他工作:'(x)=> x.DoSomething(myArgument,anotherArgument));' – HimBromBeere

+2

@HimBromBeere你包裝在一個委託中有零參數 - 正是我首先提出的。要麼這個方法必須知道這些參數,然後讓那些不符合簽名的代理沒有意義,或者它不關心參數,然後它只需要'Action'。 – Luaan

+0

是的,這是我正在尋找我現在可以傳遞方法ShowCustomDialog,它不必知道什麼樣的方法是什麼。 – Barsonax