为了账号安全,请及时绑定邮箱和手机立即绑定

何时及为何使用代表?

何时及为何使用代表?

料青山看我应如是 2019-09-27 16:34:33
我在C#中相对较新,我想知道何时适当使用Delegates。它们在事件声明中被广泛使用,但是我什么时候应该在自己的代码中使用它们,为什么它们有用? 为什么不使用其他东西?我也想知道何时必须使用委托,而没有其他选择。感谢您的帮助!编辑:我想我已经在这里找到了必要的代表使用
查看完整描述

3 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

我同意已经说过的一切,只是尝试在上面加上一些其他字眼。

可以将委托视为一种/某些方法的占位符。

通过定义委托,您对班级的用户说:“ 请随意将与该签名匹配的任何方法分配给委托,每次我的委托被调用时,都会调用该委托。”

当然,典型的用法是事件。所有OnEventX都委托给用户定义的方法。

委托对于为对象的用户提供一些自定义其行为的功能很有用。在大多数情况下,您可以使用其他方式来实现相同的目的,而且我认为您永远不会被迫创建委托。在某些情况下,这只是完成任务的最简单方法。


查看完整回答
反对 回复 2019-09-27
?
慕森王

TA贡献1777条经验 获得超3个赞

假设您要编写一个过程,以在某个时间间隔[a,b] 上集成一些实值函数f(x)。假设我们要使用3点高斯方法来做到这一点(当然任何人都可以)。


理想情况下,我们需要一些看起来像这样的函数:


// 'f' is the integrand we want to integrate over [a, b] with 'n' subintervals.

static double Gauss3(Integrand f, double a, double b, int n) {

  double res = 0;


  // compute result

  // ...


  return res;

}

因此,我们可以通过在任何Integrand,˚F,并获得其定积分在闭区间。


到底应该Integrand是什么类型?


没有代表

好吧,没有委托,我们需要一种具有单个方法的接口,eval声明如下:


// Interface describing real-valued functions of one variable.

interface Integrand {

  double eval(double x);

}

然后,我们需要创建一整套实现此接口的类,如下所示:


// Some function

class MyFunc1 : Integrand {

  public double eval(double x) {

    return /* some_result */ ;

  }

}


// Some other function

class MyFunc2 : Integrand {

  public double eval(double x) {

    return /* some_result */ ;

  }

}


// etc

然后要在我们的Gauss3方法中使用它们,我们需要按以下方式调用它:


double res1 = Gauss3(new MyFunc1(), -1, 1, 16);

double res2 = Gauss3(new MyFunc2(), 0, Math.PI, 16);

Gauss3的外观如下所示:


static double Gauss3(Integrand f, double a, double b, int n) {

  // Use the integrand passed in:

  f.eval(x);

}

因此,我们需要做的所有事情只是在中使用我们的任意函数Guass3。


与代表

public delegate double Integrand(double x);

现在,我们可以定义一些遵循该原型的静态(或非静态)函数:


class Program {

   public delegate double Integrand(double x);   

   // Define implementations to above delegate 

   // with similar input and output types

   static double MyFunc1(double x) { /* ... */ }

   static double MyFunc2(double x) { /* ... */ }

   // ... etc ...


   public static double Gauss3(Integrand f, ...) { 

      // Now just call the function naturally, no f.eval() stuff.

      double a = f(x); 

      // ...

   }


   // Let's use it

   static void Main() {

     // Just pass the function in naturally (well, its reference).

     double res = Gauss3(MyFunc1, a, b, n);

     double res = Gauss3(MyFunc2, a, b, n);    

   }

}

没有接口,没有笨拙的.eval东西,没有对象实例化,只是简单的函数指针(如用法)来完成简单的任务。


当然,委托不只是幕后的函数指针,而且这是一个单独的问题(函数链接和事件)。


查看完整回答
反对 回复 2019-09-27
  • 3 回答
  • 0 关注
  • 495 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信