Dites que vous voulez écrire une procédure pour intégrer certaines valeurs réelles de la fonction f (x) sur un certain intervalle de temps [a, b]. Disons que nous voulons utiliser les 3 Points de Gauss de la méthode pour ce faire (tout va le faire, bien sûr).
Idéalement, nous voulons une fonction qui ressemble à ceci:
// '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;
}
Nous pouvons donc passer dans tous Integrand
, f, et d'obtenir son intégrale sur l'intervalle fermé.
Juste ce type devrait Integrand
?
Sans Les Délégués
Eh bien, sans les délégués, nous avions besoin d'une sorte d'interface avec une seule méthode, disons eval
déclarée comme suit:
// Interface describing real-valued functions of one variable.
interface Integrand {
double eval(double x);
}
Alors que nous aurions besoin de créer tout un tas de classes implémentant cette interface, comme suit:
// 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
Puis à les utiliser dans notre Gauss3 méthode, nous avons besoin de l'invoquer comme suit:
double res1 = Gauss3(new MyFunc1(), -1, 1, 16);
double res2 = Gauss3(new MyFunc2(), 0, Math.PI, 16);
Et Gauss3 doit ressembler à l'exemple suivant:
static double Gauss3(Integrand f, double a, double b, int n) {
// Use the integrand passed in:
f.eval(x);
}
Nous avons donc besoin de faire tout ça juste pour utiliser nos fonctions arbitraires en Guass3
.
Avec Les Délégués
public delegate double Integrand(double x);
Maintenant, nous pouvons définir quelques statique (ou pas) de fonctions en adhérant à ce prototype:
class Program {
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);
}
}
Pas d'interfaces, pas maladroit .eval trucs, pas de l'instanciation d'objets, de simples la fonction de pointeur de l'utilisation, pour une tâche simple.
Bien sûr, les délégués sont plus que juste des pointeurs de fonction sous le capot, mais c'est une question distincte (la fonction de chaînage et d'événements).