it-swarm.cn

实际使用C#代表

我认为我在概念上理解C#代表,但是,我一直在努力寻找一个有用的现实示例。您能否提供一些答案,详细说明在实际应用程序中如何使用C#委托以及它们使您能够解决哪些问题。

16
AlexC

GUI代码使用委托来处理事件,例如按钮单击,窗口移动。使用委托可以使您确实在事件发生时调用一个函数。一个示例是将保存数据的功能链接到界面上的“保存”按钮。单击该按钮后,将其设置为执行保存数据的功能。这在GUI编程中很有用,因为您的整个程序可能正在等待用户执行某项操作,而您无法知道他们将首先执行的操作。使用委托可以将程序的功能连接到UI,使用户可以按照自己想要的任何方式进行操作。

16

Linq使用Func<T>Action<T>将整个地方委托为参数。

这些允许您将lambda表达式用作参数,并定义要作为参数列表一部分采取的操作。

12
Oded

几乎任何使用 观察者模式 的东西都可能实现委托。

阅读说明,您可能会想象一些使用它们的场景。 GUI事件处理是一个常见的示例。

12
whatsisname

委托在异步编程中很有用。

您有一个异步填充并具有回调的类。您可以在回调时调用委托方法-您的类实现将执行委托方法中描述的逻辑。

9
James Love

代表作为 中间图案中的孔 的解决方案特别有用。本质上,在很多情况下,您希望在一组通用指令中包装一组独特的指令。如果唯一位之前和之后的指令需要共享状态,则特别困难。使用委托,您可以仅将委托传递给函数。该函数执行前一位,执行委托,然后执行后一位。

9
Scott Whitlock

在非OOP语言(例如Fortran和C)的“旧时代”中,能够让子例程接收作为函数指针的参数是非常有用的。例如,qsort函数与用户提供的比较函数一起使用。有许多子例程可用于求解常微分方程或用于优化函数,它们均以函数指针作为参数。

在窗口系统中,各种回调都遵循相同的模式。

在LISP中,即使在早期,也有一种称为“函数参数”或FUNARG的东西,它不仅是一个函数,而且还包含一个存储上下文,可以在其中记忆并与外界交互。

在OOP=)语言中也存在相同的需求,除了传递函数的地址时,还必须传递函数作为方法的对象的地址。这是必须传递的两件事因此,委托就是这样,并且允许仍然使用该旧模式。

5
Mike Dunlavey

这是一个简单的示例,显示了委托在创建遵循DRY)原理的简单代码方面的有用性。它还使您可以将代码保持在非常需要的地方。

Action<Button, Action<Button>> prepareButton = 
    (btn, nxt) => { 
        btn.Height = 32;
        btn.Width= 64;
        nxt(btn);
    };

prepareButton(myBtn1, btn => btn.Text = "A");
prepareButton(myBtn2, btn => btn.Text = "B");
prepareButton(myBtn3, btn => btn.Text = "C");

这是代表提供的优势的真实示例。

protected override void PageInitialize()
{
    const string selectCodeFormat = "javascript:selectCode('{0}', '{1}');";
    const string onClick = "return toggleElement(this);";

    Func<HtmlGenericControl> getElement = null;
    Action<HtmlGenericControl> setElement = null, addChild = null;
    HtmlGenericControl level1Element = null, level2Element = null, level3Element = null, level4Element = null;
    string className = null, code = null, description = null;           

    using (var records = Core.Database.ExecuteRecords("code.SocCodeTree"))
    {
        while (records.Read())
        {
            code = records.GetString("Code");
            description = records.GetString("Description"); 

            if (records.GetString("Level4") != "")
            {
                className = "Level4";
                setElement = e => level4Element = e;
                getElement = () => level4Element;
                addChild = e => level3Element.Controls.Add(e);
            }
            else if (records.GetString("Level3") != "")
            {
                className = "Level3";
                setElement = e => level3Element = e;
                getElement = () => level3Element;
                addChild = e => level2Element.Controls.Add(e);
            }
            else if (records.GetString("Level2") != "")
            {
                className = "Level2";
                setElement = e => level2Element = e;
                getElement = () => level2Element;
                addChild = e => level1Element.Controls.Add(e);
            }
            else
            {
                className = "Level1";
                setElement = e => level1Element = e;
                getElement = () => level1Element;
                addChild = e => Root.Controls.Add(e);
            }

            var child = new HtmlGenericControl("li");
            child.Attributes["class"] = className;
            var span = new HtmlGenericControl("span") { 
                InnerText = code + " - " + description + " - " 
            };
            span.Attributes["onclick"] = onClick;
            child.Controls.Add(span);
            var a = new HtmlAnchor() { 
                InnerText = "Select", 
                HRef = string.Format(selectCodeFormat, code, description) 
            };
            child.Controls.Add(a);
            setElement(new HtmlGenericControl("ul"));
            child.Controls.Add(getElement());
            addChild(child);    
        }
    }
}
3
ChaosPandion

我与委托的第一次接触是通过从我的网站下载文件来检查程序更新(Windows窗体C#3.5),但是为了避免更新检查锁定整个程序,我使用了委托和线程来异步进行更新。

2
Ken

我已经看到了有效使用委托的Strategy模式的有趣实现。 (即该策略是代表)

我正在查看的是路径查找,其中查找路径的算法是可以在运行时(重新)分配给它的委托,以便可以使用不同的算法(BFS与A *等)。

1
Steven Evers

许多经典的GoF模式都可以使用委托来实现:例如,命令模式,访问者模式,策略模式,工厂模式和观察者模式通常可以通过简单的委托来实现。有时,类会更好(例如,当命令需要名称或需要序列化策略对象时),但是在大多数情况下,使用Action<...> 要么 Func<...>比创建专用的单方法界面要优雅得多。

1
nikie