带有参数的委托作为参数

8

我有一个方法及其委托,用于从我的WinForms应用程序的任何线程向多行文本框中追加文本:

private delegate void TextAppendDelegate(TextBox txt, string text);
public void TextAppend(TextBox txt, string text)
{
  if(txt.InvokeRequired)
    txt.Invoke(new TextAppendDelegate(TextAppend), new object[] {txt, text });
  else
  {
    if(txt.Lines.Length == 1000)
    {
      txt.SelectionStart = 0;
      txt.SelectionLength = txt.Text.IndexOf("\n", 0) + 1;
      txt.SelectedText = "";
    }
    txt.AppendText(text + "\n");
    txt.ScrollToCaret();
  }
}

这个功能很棒,我只需要从任何一个线程中调用TextAppend(myTextBox1, "Hi Worldo!"),就可以更新GUI。现在,有没有一种方法可以将调用TextAppend的委托传递给我的另一个项目中的某个实用程序方法,而不发送任何对实际TextBox的引用,像这样从调用者的角度看:

Utilities.myUtilityMethod(
    new delegate(string str){ TextAppend(myTextBox1, str) });

在被调用方,可以使用类似如下定义的方式:
public static void myUtilityMethod(delegate del)
{
    if(del != null) { del("Hi Worldo!"); }
}

当调用此函数时,它会使用该字符串和调用者想要使用的预定义 TextBox 调用 TextAppend 方法。这种做法可行吗?还是我太疯狂了?我知道有更简单的选择,比如使用接口或传递 TextBox 和委托,但我想探索这种解决方案,因为它似乎更优雅,并且可以隐藏来自被调用者的信息。问题是,我在 C# 中还是太菜了,几乎不理解委托,请帮我处理一下实际的语法,谢谢!

1
.NET/C# 的版本是什么? - Platinum Azure
1
你不能将整个TextAppend方法移动到你的实用类中,然后从调用者处使用Utility.TextAppend(MyTextbox, "foo")吗? - Dylan Smith
1
为了更好地了解您的需求,有几个问题。您希望您的 myUtilityMethod 如何知道它必须将单个字符串传递给委托?您希望它如何获取要传递的字符串? - Enigmativity
@Platinum Azure 版本号是 3.5。 - R. Ruiz.
1
@RRuiz 如果你将TextAppend移动到Utility类中,你就不需要传递一个委托,因为TextAppend会自己创建它。你只需要传递一个文本框的引用和要附加的字符串即可。对我来说,这听起来像是一个完美的实用方法(我也可能会将其作为TextBox类的扩展方法)。 - Dylan Smith
显示剩余3条评论
1个回答

15

假设您正在使用C#3(VS2008)或更高版本:

Utilities.myUtilityMethod(str => TextAppend(myTextBox1, str));

...

public static void myUtilityMethod(Action<string> textAppender)
{
    if (textAppender != null) { textAppender("Hi Worldo!"); }
}

如果您正在使用 .NET 2.0,您可以使用匿名方法来代替 lambda 表达式:

Utilities.myUtilityMethod(delegate(string str) { TextAppend(myTextBox1, str); });

如果您使用的是.NET 1.x,您需要自己定义委托并使用命名方法:

delegate void TextAppender(string str);

void AppendToTextBox1(string str)
{
    TextAppend(myTextBox1, str);
}

...

Utilities.myUtilityMethod(new TextAppender(AppendToTextBox1));

...

public static void myUtilityMethod(TextAppender textAppender)
{
    if (textAppender != null) { textAppender("Hi Worldo!"); }
}

太好了!我测试了Lambda表达式和匿名方法,它们都完美无缺地工作。即使我不想执行任何操作,空值条件也可以正常工作。非常感谢! - R. Ruiz.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接