Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic function declaration in C#

Tags:

c#

generics

I'm trying to create some stats about method call duration in a library. Instead of wrapping each method call to the library with lines to time and track it, I want to create a generic action and function which does these recurring steps.

E.g. for methods that don't return a value, I have created this:

    private readonly Action<string, Action> timedAction = (name, action) =>
    {
        var sw = Stopwatch.StartNew();
        action.Invoke();
        trackDuration(name, sw.ElapsedMilliseconds);
    };

That can be invoked with timedAction("methodname", () => lib.methodname()).

I want to do something similar for methods that return a value, but obviously Action can't be used for that purpose, since it can't return a value.

Is there a way to do this with a generic Func, so I don't have to declare one for each combination of library method parameters?

like image 986
RasmusW Avatar asked Oct 26 '16 07:10

RasmusW


People also ask

What is generic function in C?

Generic functions are functions declared with one or more generic type parameters. They may be methods in a class or struct , or standalone functions. A single generic declaration implicitly declares a family of functions that differ only in the substitution of a different actual type for the generic type parameter.

How do you write a generic function?

Functions can create generics by adding the type parameter list <T> before the function parameter list. You can use generics in the same places you'd add any other type in a function (parameter or return types). function method<T>(param: T): T { // ... }

Is there generic in C?

Generics are syntax components of a programming language that can be reused for different types of objects. Typically, generics take the form classes or functions, which take type(s) as a parameter.

What is generic name function?

In some systems for object-oriented programming such as the Common Lisp Object System (CLOS) and Dylan, a generic function is an entity made up of all methods having the same name. Typically a generic function is an instance of a class that inherits both from function and standard-object.


2 Answers

You can use a generic function like this:

private static TValue FuncHandler<TValue>(string name, Func<TValue> func)
{
    var sw = Stopwatch.StartNew();
    var result = func();

    trackDuration(name, sw.ElapsedMilliseconds);

    return result;
}

Call it like this:

var result = FuncHandler("name", () => MyMethod(param1));
like image 180
selami Avatar answered Oct 01 '22 23:10

selami


Indeed, AOP will buy you more than this sort of tediousness:

https://dotnetfiddle.net/5PLCmM

// Needs to be replicated after Func<T1, TResult>, Func<T1, T2, TResult>, etc, for all the functions arities you'll want to wrap with it
public static TResult Timed<T1, /*T2, etc*/TResult>(out long duration, Func<T1, /*T2, etc*/TResult> func, T1 arg1/*T2 arg2, etc*/)
{
    //start timing
    var t0 = DateTime.Now;
    var result = func(arg1/*, arg2, etc*/);
    //end timing
    duration = (long)DateTime.Now.Subtract(t0).TotalMilliseconds;
    return result;
}

public int Factorial(int n)
{
    return n > 0 ? n * Factorial(n - 1) : 1;
}

public int Fibonacci(int n)
{
    return n > 1 ? Fibonacci(n - 2) + Fibonacci(n - 1) : n;
}

public static void Main()
{
    var program = new Program();

    long duration;

    var _12bang = Timed(out duration, program.Factorial, 12);

    Console.WriteLine("{0}! = {1} in {2} ms", 12, _12bang, duration);

    var fib31 = Timed(out duration, program.Fibonacci, 31);

    Console.WriteLine("Fib {0} = {1} in {2} ms", 31, fib31, duration);

}

(yes, I know about StopWatch; was just too lazy to put it in there)

'Hope this helps.

like image 40
YSharp Avatar answered Oct 01 '22 22:10

YSharp