代表们有哪些优势?

时间:2009-03-12 16:04:59

标签: c# .net delegates

使用代表有什么好处/好处?任何人都可以提供任何简单的例子吗?

7 个答案:

答案 0 :(得分:43)

它们是封装一段代码的好方法。例如,当您将事件处理程序附加到按钮时,该处理程序是委托。该按钮不需要知道它的作用,只是如何在正确的时间调用它。

另一个例子是LINQ - 过滤,投影等都需要相同类型的模板代码;所有这些变化都是表示过滤器,投影等的逻辑。使用C#3中的lambda表达式(转换为委托或表达式树),这非常简单:

var namesOfAdults = people.Where(person => person.Age >= 18)
                          .Select(person => person.Name);

(也可以表示为查询表达式,但是不要偏离代表那么远。)

另一种思考委托的方式是作为单方法接口类型。例如,EventHandler委托类型有点像:

public interface IEventHandler
{
    void Invoke(object sender, EventArgs e)
}

但是框架中的委托支持允许委托链接在一起,异步调用,用作事件处理程序等。

有关代理和活动的更多信息,请参阅my article on the topic。它的重点是活动,但也包括代表。

答案 1 :(得分:13)

这是一个非常含糊的话题,但这里有几点需要考虑 -

代理基本上是一个更简洁,更容易的函数指针。在C ++中使用函数指针的任何地方,你都可以认为是委托。

在设计中使用它们的优点:

  • 可以轻松重用代码
  • 可以为您的设计提供极大的灵活性
  • 允许您开发易于扩展的库和类,因为它提供了一种简单的方法来挂钩其他功能(例如,LINQ中的where子句可以使用委托[Func<T,bool>]进行过滤,而无需在Where方法中编写新代码

潜在的劣势:

  • 他们~can~,特别是如果天真地使用,会导致代码更难以阅读
  • 他们可以在您的组件中引入意外行为,因为您的控件中的第三方代码将被调用(例如,如果有人将委托附加到导致无限循环的某个事件,它可以使您的类看起来不好,即使它与你无关)。

答案 2 :(得分:5)

代表有三个目的:

  1. Observer模式的简化实现
  2. 回调的简化实现
  3. 匿名(不可重复使用)代码块
  4. 观察

    public class Something
    {
        public event EventHandler SomethingHappened;
    }
    
    public class SomethingConsumer
    {
        private mySomething = new Something();
    
        public void WireUpEvents()
        {
            mySomething.SomethingHappened += whenSomethingHappened;
        }
    
        private void whenSoemthingHappened(object sender, EventArgs e)
        {
            // do something
        }
    }
    

    回调

    public void DoSomethingAsynchronously(EventHandler callBack)
    {
        // long running logic.
        callBack(this, EventArgs.Empty);
    }
    

    匿名不可重复使用的代码

    public void DoSomethingReusably(Action nonReusableCode)
    {
        // reusable code
        nonReusableCode();
        // more reusable code
    }
    
    public void DoALotOfSomething()
    {
        DoSomethingReusably(() => { /* non-reusable code here */ });
        DoSomethingReusably(() => { /* non-reusable code here */ });
        DoSomethingReusably(() => { /* non-reusable code here */ });
    }
    

    在所有情况下,这只是提供简洁性的问题。

答案 3 :(得分:2)

C#中的委托是eqv。在C中使用指针,但它也带有对它创建的类实例的引用。

Windows窗体中的所有事件处理程序都是委托。

答案 4 :(得分:2)

相比什么优势?代表可以是有用的东西,并且肯定在许多中等复杂的C#代码中占有一席之地。 (无论何时在类中使用事件,您都隐式使用多播委托)。如果您想了解它们的语法和用法,我推荐以下文章:

答案 5 :(得分:2)

免责声明:我不是说我如何使用委托是预期的方式,但它是一个例子。

我之前只使用过一次,但基本上在我们的应用程序中,用户单击“完成”按钮进行一个步骤,然后将它们带到路由页面以决定下一步发送它的位置。所以从技术上来说,他们刚刚点击“完成”的步骤并没有真正完成,直到他们路由它。但是因为我在另一个页面上,所以我并没有轻易访问他们的位置。

所以我所做的是为点击“完成”时需要特殊处理的几个步骤(在本例中为电子邮件)创建了一个委托,当他们在下一页上路由它时,我会检查是否存在代表,如果是,那就叫它来解雇我的'存储'事件。

创意:可能,错误:也许,工作:肯定。

就像我说的可能不是如何使用它,但编码与科学一样多吗?

答案 6 :(得分:1)

我记得早期的Java GUI框架没有委托或命令路由的概念。为了创建一个执行某些操作的按钮,您必须子类Button 并覆盖click方法。你最终得到了大量的UI元素子类,其中包含了很少的应用程序代码。

处理该点击的代码必须去某个地方,并且在像Java或C#这样的OO语言中,它必须继续上课,但代表允许它在方便的地方发生。这通常会导致代码中有太多代码在表单类中执行太多不同的事情,但这是一个不同的问题。