如何使用 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"));
我很难理解委托,为此我为自己创建了一个简单的示例,但它没有按照我想要的方式工作,这是我的示例:
我的功能:
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"));