簡體   English   中英

如何使用C#中的參數委托將兩個函數傳遞給另一個函數

[英]How to pass two function to another function with a delegate for parameters in C#

我正在努力理解代表,為此我為自己創建了一個簡單的示例,但它並不能達到我想要的方式,這是我的示例:

我的職能:

class Functions
{

    public string MyFname(string MyString) 
    {

        return MyString;


    }
    public string MyLname(string MyString)
    {

        return MyString;


    }


}

代表:

class DelClass
{
    public delegate string StrDelegate(string OutPutString);

    public void StringCon(StrDelegate Fname,StrDelegate Lname) 
    {

        Console.WriteLine(Fname + " " + Lname);

    }
}

主要:

class Program
{
    static void Main(string[] args)
    {
        DelClass MyDel = new DelClass();
        Functions MyTster = new Functions();
        DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname);
        Name("SomeVariableName");
        DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname);
        Family("SomeVariableFamilyName");
        MyDel.StringCon(Name, Family);

    }
}

問題是控制台窗口沒有顯示我傳遞的字符串,而是顯示了下面提到的文本:

MyDelegateMethodInMethod.DelClass + StrDelegate MyDelegateMethodInMethod.DelClass + StrDelegate

當我嘗試像這樣調用StringCon主體中的傳遞函數時:

Console.WriteLine(Fname() + " " + Lname();

編譯器抱怨“ Delegate'StrDelegate'不接受0個參數”,但是我不想在StringCon的傳遞參數中傳遞參數,我想在Main函數中傳遞它,甚至可以使用委托嗎?

委托是包含對方法的引用的對象。 調用委托具有執行該方法的效果。 您的兩個方法每個都有一個String參數,因此要傳遞這些方法中的任何一個,都需要傳遞一個String參數。 這意味着,當您調用委托時,他們需要將單個String參數傳遞給他們執行的方法。 您認為價值將來自何處? 代表不會憑空摘下它。 調用它時,必須將其傳遞給委托。 在此代碼中:

public void StringCon(StrDelegate Fname,StrDelegate Lname) 
{
    Console.WriteLine(Fname + " " + Lname);
}

你在哪兒 你不是。 您必須將參數提供給委托人,以便他們將其提供給方法:

public void StringCon(StrDelegate Fname,StrDelegate Lname) 
{
    Console.WriteLine(Fname("John") + " " + Lname("Doe"));
}

但是,這是一個非常糟糕的演示,因為您的方法實際上並沒有做任何有用的事情。 如何定義一個方法如何做一些有用的事情:

public string GetFullName(string givenName, string familyName)
{
    return givenName + " " + familyName;
}

和一個相應的代表:

public delegate string FullNameGetter(string givenName, string familyName);

然后像這樣調用它:

var fng = new FullNameGetter(GetFullName);

Console.WriteLine(fng("John", "Doe"));

如果您不想傳遞字符串作為輸入,則應適當地聲明委托:

class DelClass
{
    public delegate string StrDelegate();
    public void StringCon(StrDelegate Fname,StrDelegate Lname) 
    {
        Console.WriteLine(Fname() + " " + Lname());
    }
}

從編寫的內容來看,您想將string屬性保存在某個地方-但是委托不是放置它的地方。您可以使用FName,LName屬性創建一個對象:

class Functions
{
    public string MyFname() { return MyFnameProperty; }
    public string MyLname() { return MyLnameProperty; }
    public string MyFnameProperty { get; set; }
    public string MyLnameProperty { get; set; }
}

最后,在Main中,您將編寫:

class Program
{
    static void Main(string[] args)
    {
        DelClass MyDel = new DelClass();
        Functions MyTster = new Functions();
        DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname);
        MyTster.MyFnameProperty ="SomeVariableName";
        DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname);
        MyTster.MyLnameProperty = "SomeVariableFamilyName";
        MyDel.StringCon(Name, Family);
    }
}

這實際上不是應該使用委托的方式,委托主要用作回調函數,用於EventHandler或在您喜歡調用函數時使用。

EventHandler的示例可以是

public delegate void ReportErrorDelegate(object sender, MyCustomEventArgs e);

與一堂課

public class MyCustomEventArgs : EventArgs
{
     // some implementation
     public MyCustomEventArgs() 
     {
     }

     public MyCustomEventArgs(object argument)
         : this()
     {
         ....
     }
}

然后,您可以創建一個基於您的代表的事件

public interface IRaiseMyCustomEventArgs
{
     event ReportErrorDelegate CustomEventFired;
}

然后可以將其實現為

public class RaiseMyCustomEventArgs : IRaiseMyCustomEventArgs
{
     public event ReportErrorDelegate CustomEventFired;

     protected virtual void RaiseCustomEventArgs(object argument)
     {
         var local = CustomEventFired;
         if (local != null) {
             local.Invoke(this, new MyCustomEventArgs(argument));
         }
     }
}

另一個選擇是在檢測到需要調用UI交互后重新調用方法,例如

public delegate void SetTextDelegate(TextBox tb, string text);

public void SetText(TextBox tb, string text)
{
     if (tb.InvokeRequired) 
     {
          tb.Invoke(new SetTextDelegate(SetText), tb, text);
          return;
     }
     tb.Text = text;
}

這將從Windows應用程序內部運行的線程中調用(例如)

public void RunThread() 
{
     // assuming TextBox1 exists on the form
     Thread t = new Thread(() => {
         SetText(TextBox1, "Hello World");
     });
     t.Start();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM