14

我想知道使用委托方法和使用一般方法[没有委托]之间的区别。

例如 :


与代表:

delegate void DelMethod(string str);

static void Method(string str)
{
    Debug.WriteLine(str);
}

用法 :

DelMethod dm = new DelMethod(Method);
dm(string);

并且没有代表:

static void Method(string str)
{
    Debug.WriteLine(str);
}

用法 :

Method(string)

这两个有什么区别??

没有委托的方法更小更容易。但我发现编码人员经常使用委托方法。

这背后的原因是什么??

4

4 回答 4

20

想象一个场景,您有一个搜索客户的函数。最初您只想按名称搜索,因此您可以编写如下内容:

public Customer Find(string name)
{
    foreach (var customer in database.Customers)
       if (customer.Name == name)
          return customer;
}

然后你的规范改变了,你必须实现新的搜索方式(比如说“按地址搜索”)。没问题,我们将旧代码重构为:

public Customer FindByName(string name)
{
    foreach (var customer in database.Customers)
       if (customer.Name == name)
          return customer;
}

public Customer FindByAddress(string address)
{
    foreach (var customer in database.Customers)
       if (customer.Address == address)
          return customer;
}

它们看起来非常相似,不是吗?

现在您的老板再次告诉您添加另一个搜索功能,用户可能希望通过电话号码查找客户。越来越无聊了,不是吗?

幸运的是,开发人员已经找到了一种让其他开发人员的生活更轻松的方法来发明委托。使用它们,您可以创建一个更大的通用函数,帮助您避免一次又一次地重写相同的代码。

public Customer Find(Predicate<Customer> p)
{
    foreach (var customer in database.Customers)
       if (p(customer))
          return customer;
}

现在,您不必在每次需要一种新的搜索客户方式时都创建一个专门的函数,因此您可以编写:

var byName = Find(a => a.Name == "lorem");
var byAddress = Find(a => a.Address == "ipsum");
var byTelephone = Find(a => a.Telephone == "dolor");

委托对于管理事件也很有用,并且在 LINQ 中也被大量使用。只需谷歌“delegates c#”,您就会发现一个巨大的新世界!:)

于 2012-05-22T17:54:07.853 回答
6

代表们是另一种情况。想象一下,你有一个班级应该回答另一个班级的问题,但你对第二个班级一无所知。在这种情况下,您可以先做一个委托。

// class where you know something
class A
{
   //delegate for answer
   public Func<bool> AskForSomething { get; set; }

   public void DoSomething()
   {
      //some code
      if(AskForSomething())
      {
          //do something
      }
      else
      {
          //do something else
      }
   }
}

class B
{
   public void Test()
   {
      A a = new A();
      a.AskForSomething = new Func<bool>(Answer);
      a.DoSomething();
   }

   private bool Answer()
   {
       return true;
   } 
}

Class A什么都不知道class B,但它可以调用 B 的方法并得到它的结果。里面的Answer方法class B私有的,class A不能直接调用。

在MSDN中阅读更多内容

于 2012-05-22T17:34:10.473 回答
4

在一种特殊情况下,两个调用会有所不同,即当涉及到可选参数时。考虑这些

delegate void DelMethod(string str = "hai");  
static void Method(string str = "bye")
{
    Debug.WriteLine(str);
}

DelMethod dm = Method;
dm();

//prints "hai"

Method();

//prints "bye"

在第一种情况下,它是在调用站点插入的委托的可选参数。

于 2013-12-22T03:56:39.063 回答
3

代表的另一种用法:

如果没有委托,只有定义私有方法的类才能调用这些方法。通过在委托中包装方法,您可以将委托实例传递给其他类,并让它们使用适当的参数调用委托(作为回调),最终将在定义类中调用您的实际私有方法。


例如 :

namespace DelegatesSample
{
    public delegate void privateCallbackDelegate(string param1, int param2);
    public class A
    {
        private void DelegatedMehod(string param1, int param2)
        {
            //Code for some action
        }

        private void CallBusinessClass()
        {
            privateCallBackDelegate del = new privateCallBackDelegate(DelegateMethod);

            B b = new B();
            b.InvokeBusinessMethod(del);
        }
    }

    public class B
    {        
        public void InvokeBusinessMethod(privateCallbackDelegate d)
        {
            //Do Some calculations and when finished, call the callback delegate
            d("Done", result); //or d.Invoke or d.BeginInvoke
        }

    }
}

一般来说,MSDN 在这篇文章中有以下说法:

代表在以下情况下很有用:

  • 正在调用一个方法。
  • 一个类可能需要方法规范的多个实现。
  • 希望允许使用静态方法来实现规范。
  • 需要类似事件的设计模式(有关更多信息,请参阅事件教程)。
  • 调用者无需知道或获取定义该方法的对象。
  • 实现的提供者希望仅将规范的实现“分发”给少数选定的组件。
  • 需要简单的组合。
于 2012-05-22T17:57:35.017 回答