如何使用 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);

    }
}

问题是控制台 window 不显示我传递的字符串,而是显示下面提到的文本:

MyDelegateMethodInMethod.DelClass+StrDelegate MyDelegateMethodInMethod.DelClass+ StrDelegate

当我尝试像这样调用 StringCon 主体中传递的函数时:

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

编译器抱怨 "Delegate 'StrDelegate' does not take 0 arguments" 但我不想在 StringCon 传递的参数中传递一个参数,我想在我的 Main 函数中这样做,这甚至可以用委托吗?

如果您不想将字符串作为输入传递,您应该适当地声明委托:

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

从你写的内容来看,你想将字符串 属性 保存在某处 - 但委托不是该做的地方 it.You 可以创建一个具有 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 的示例可以是

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

class

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();
}

委托是包含对方法的引用的对象。调用委托具有执行方法的效果。您的两个方法每个都有一个 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"));