【问题标题】:Delegate with parameters... as a parameter带参数的委托...作为参数
【发布时间】:2011-10-28 06:57:49
【问题描述】:

我有这个方法及其委托,用于从我的 WinForms 应用程序中的任何线程将文本附加到 GUI 中的多行文本框:

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# 的新手,几乎不了解委托,所以请帮助我了解可行的实际语法。

提前致谢!

【问题讨论】:

  • 什么版本的 .NET/C#?
  • 你不能把整个 TextAppend 方法移动到你的实用程序类中,然后从调用者那里执行 Utility.TextAppend(MyTextbox, "foo") 吗?
  • 几个问题可以更好地了解您的要求。您如何期望您的 myUtilityMethod 知道它必须将单个字符串传递给您的委托?你希望它如何让字符串通过?
  • @Platinum Azure 版本是3.5
  • @RRuiz 如果将 TextAppend 移动到 Utility 类中,则不需要传递委托,因为 TextAppend 会创建它。您只需传递对文本框的引用和要附加的字符串。对我来说,这听起来像是对实用方法的完美使用(我也可能将其作为 TextBox 类的扩展方法)。

标签: c# parameters delegates


【解决方案1】:

假设您使用的是 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 表达式和匿名方法,它们完美地工作。如果我不想执行任何操作,即使 null 条件也有效。非常感谢!
猜你喜欢
  • 2013-11-17
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多