2009-01-29 19 views
8

我想我理解C#中委托的概念作为指向方法的指针,但是我无法找到任何使用它们的好主意的好例子。什么是一些例子,或者更好或更好的委托或不能用其他方法解决?C# - 有人能告诉我为什么和我应该在哪里使用代表?

+0

天哪,我在一年前问过这个问题,现在很难想象代表/ lambda表达式之前的生活!我不得不说,这里的答案仍然是网上最好的例子。这就是SO的力量。 – Alex 2009-12-29 16:39:59

回答

6

究竟你代表是什么意思?这里有两种方法可以使用它们:

void Foo(Func<int, string> f) { 
//do stuff 
string s = f(42); 
// do more stuff 
} 

void Bar() { 
Func<int, string> f = delegate(i) { return i.ToString(); } 
//do stuff 
string s = f(42); 
// do more stuff 
} 

在第二个问题是,你可以在飞行中宣布新的功能,如委托。这可以在很大程度上被lambda表达式所取代,并且在您想要1)传递给另一个函数或2)只需重复执行一小段逻辑时,它就很有用。 LINQ就是一个很好的例子。每个LINQ函数都将lambda表达式作为参数,指定行为。例如,如果您有List<int> ll.Select(x=>(x.ToString())将在列表中的每个元素上调用ToString()。我写的lambda表达式是作为委托来实现的。

第一个案例显示了Select如何实现。你拿一个委托人作为你的论点,然后在需要时调用它。这允许调用者自定义该功能的行为。再次以Select()为例,函数本身保证传递给它的委托将在列表中的每个元素上被调用,并且每个元素的输出将被返回。那个代表实际上确实取决于你。这使得它变得非常灵活和一般的功能。

当然,他们也用于订阅活动。简而言之,代表允许您引用函数,在函数调用中将它们用作参数,将它们分配给变量以及您喜欢做的任何其他操作。

6

我主要使用简单的异步编程。开始使用代表的方法Begin ...方法非常简单,如果你想开火并忘记。

代理也可以使用接口不可用时的接口。例如。调用COM类的方法,外部.Net类等。

0

这里没有任何东西可以解决其他方法无法解决的问题,但它们提供了更优雅的解决方案。

对于代表,只要具有所需的参数,可以使用任何函数。

另一种方法是经常使用的一种定制事件系统的程序,创建错误额外的工作和更多的领域中

11

的.NET 1.0代表蠕变:

this.myButton.Click += new EventHandler(this.MyMethod); 

的.NET 2.0代表:

this.myOtherButton.Click += delegate { 
    var res = PerformSomeAction(); 
    if(res > 5) 
     PerformSomeOtherAction(); 
}; 

它们看起来很有用。如何:

new Thread(new ThreadStart(delegate { 
    // do some worker-thread processing 
})).Start(); 
+0

这简直太棒了!了解 – SMUsamaShah 2014-05-12 23:22:06

4

事件是最明显的例子。比较观察者模式在Java(接口)和C#(委托)中的实现方式。另外,很多新的C#3功能(例如lambda表达式)都基于委托并进一步简化了它们的使用。

3

例如在多线程应用程序中。如果你想要几个线程使用一些控制,你可以使用代表。对不起,代码是在VisualBasic中。

首先声明一个委托

Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean) 

编写一个函数,从多个线程

Private Sub enable_button(ByVal enabled As Boolean) 
    If Me.ButtonConnect.InvokeRequired Then 

     Dim del As New ButtonInvoke(AddressOf enable_button) 
     Me.ButtonConnect.Invoke(del, New Object() {enabled}) 
    Else 
     ButtonConnect.Enabled = enabled 
    End If 

End Sub 
2

我使用它们所有与LINQ的时候,尤其是lambda表达式启用/禁用按钮,提供评估条件或返回选择的函数。也可以使用它们来提供一个函数,将比较两个项目进行排序。后者对于默认排序可能适用或不适用的泛型集合非常重要。

var query = collection.Where(c => c.Kind == ChosenKind) 
         .Select(c => new { Name = c.Name, Value = c.Value }) 
         .OrderBy((a,b) => a.Name.CompareTo(b.Name)); 
2

委托的好处之一是异步执行。

当您异步调用某个方法时,您不知道它何时会完成执行,因此您需要将委托传递给该方法,该方法指向另一个将在第一个方法完成执行时调用的方法。在第二种方法中,您可以编写一些代码来通知您执行已完成。

1

其他一些评论谈到了异步世界......但自从做这样的我最喜欢的“味道”已经提到无论如何,我会发表评论:

ThreadPool.QueueUserWorkItem(delegate 
{ 
    // This code will run on it's own thread! 
}); 

此外,与会代表了巨大的原因是为了“回调”。比方说,我做了一点功能(异步),你要我打电话给一些方法(假设“AlertWhenDone”)...你可以通过在“委托”给你的方法如下:

TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone); 
1

除了他们在事件中的角色外,如果您使用winforms或asp.net,您可能会熟悉这些角色,委派对于使类更灵活(例如,在LINQ中使用它们的方式)非常有用。

“寻找”事物的灵活性很常见。你有一些东西,你想提供一种方法来查找东西。现在,您可以允许调用者提供算法,以便他们可以搜索您的收藏集,但他们认为合适,而不是猜测某人可能想要查找的每种方式。

这里有一个简单的代码示例:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Delegates 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Collection coll = new Collection(5); 
      coll[0] = "This"; 
      coll[1] = "is"; 
      coll[2] = "a"; 
      coll[3] = "test"; 

      var result = coll.Find(x => x == "is"); 

      Console.WriteLine(result); 

      result = coll.Find(x => x.StartsWith("te")); 

      Console.WriteLine(result); 

    } 

} 

public class Collection 
{ 
    string[] _Items; 

    public delegate bool FindDelegate(string FindParam); 

    public Collection(int Size) 
    { 
     _Items = new string[Size]; 

    } 

    public string this[int i] 
    { 
     get { return _Items[i]; } 
     set { _Items[i] = value; } 
    } 

    public string Find(FindDelegate findDelegate) 
    { 
     foreach (string s in _Items) 
     { 
      if (findDelegate(s)) 
       return s; 
     } 
     return null; 
    } 

} 
} 

输出

测试

2

技术上委托是用于封装具有特定签名的方法和返回类型

0

是否有与外部调用数据库打交道时,使用委托的优势,引用类型?

例如可以代码:

static void Main(string[] args) { 

      DatabaseCode("test"); 

} 

public void DatabaseCode(string arg) { 

      .... code here ... 

} 

在代码B加以改进:

static void Main(string[] args) { 

      DatabaseCodeDelegate slave = DatabaseCode; 
      slave ("test"); 

} 

public void DatabaseCode(string arg) { 

      .... code here ... 

} 
public delegate void DatabaseCodeDelegate(string arg); 

看来,这是主观的,但其中也有很强的相互矛盾的观点的区域?