C # passerende functie als argument

Ik heb een functie geschreven in C # die een numerieke differentiatie doet. Het ziet er zo uit:

public double Diff(double x)
{
    double h = 0.0000001;
    return (Function(x + h) - Function(x)) / h;
}

Ik zou graag in staat zijn om in elke functie te gaan, zoals in:

public double Diff(double x, function f)
{
    double h = 0.0000001;
    return (f(x + h) - f(x)) / h;
}

Ik denk dat dit mogelijk is met afgevaardigden (misschien?) Maar ik weet niet zeker hoe ik ze moet gebruiken.

Elke hulp zou zeer op prijs worden gesteld.


Antwoord 1, Autoriteit 100%

Gebruik van de FUNC zoals hierboven vermeld werken, maar er zijn ook afgevaardigden die dezelfde taak doen en ook intenties definiëren binnen de naamgeving:

public delegate double MyFunction(double x);
public double Diff(double x, MyFunction f)
{
    double h = 0.0000001;
    return (f(x + h) - f(x)) / h;
}
public double MyFunctionMethod(double x)
{
    // Can add more complicated logic here
    return x + 10;
}
public void Client()
{
    double result = Diff(1.234, x => x * 456.1234);
    double secondResult = Diff(2.345, MyFunctionMethod);
}

Antwoord 2, Autoriteit 116%

Er zijn een paar generieke typen in .NET (V2 en later) die passerende functies in de buurt zijn als afgevaardigden zeer eenvoudig.

Voor functies met retourtypen is er func & lt; & gt; En voor functies zonder retourtypen is er actie & lt; & gt;

Zowel Func als Action kunnen worden gedeclareerd met 0 tot 4 parameters. Bijvoorbeeld Func < dubbel, int > neemt een double als parameter en retourneert een int. Actie < dubbel, dubbel, dubbel > neemt drie dubbele waarden als parameters en retourneert niets (void).

Dus je kunt je Diff-functie declareren om een Func te nemen:

public double Diff(double x, Func<double, double> f) {
    double h = 0.0000001;
    return (f(x + h) - f(x)) / h;
}

En dan noem je het zo, door het simpelweg de naam te geven van de functie die past bij de handtekening van je Func of Action:

double result = Diff(myValue, Function);

Je kunt de functie zelfs in-line schrijven met lambda-syntaxis:

double result = Diff(myValue, d => Math.Sqrt(d * 3.14));

Antwoord 3, autoriteit 12%

public static T Runner<T>(Func<T> funcToRun)
{
    //Do stuff before running function as normal
    return funcToRun();
}

Gebruik:

var ReturnValue = Runner(() => GetUser(99));

Other episodes