Yurrili
Yurrili

Reputation: 338

Method returns delegate which is multiplied value of delegates from paramiters

I need to defined method, which gets as parameters two delegates, and return delegate (which will multiplied return of this delegates from paramiters). For now i have sth like that, but i can't make it compile-able. Could you give some advise, or answer ? I will be very grateful.

public Delegate MathP(Delegate mydelegate, Delegate mydelegate2)
    {

        return (Delegate) Delegate.CreateDelegate Delegate (int x, int y) {
                 int results = (int)mydelegate.DynamicInvoke(x, y);
                 int results2 = (int)mydelegate2.DynamicInvoke(x, y);

                 return results* results2;
            };
    }

Upvotes: 1

Views: 44

Answers (2)

Patrick Hofman
Patrick Hofman

Reputation: 157098

If you can rewrite your delegates to Func's, it is rather easy to do:

public Func<int, int, int> MathP
    ( Func<int, int, int> mydelegate
    , Func<int, int, int> mydelegate2
    )
{
    return new Func<int, int, int>
        ( (x, y) => mydelegate(x, y) * mydelegate2(x, y)
        );
}

Upvotes: 3

galenus
galenus

Reputation: 2137

You probably better use expression trees. This method will produce the result you expect:

static Delegate Combine(Delegate first, Delegate second)
{
    var firstParam = Expression.Parameter(typeof(int));
    var secondParam = Expression.Parameter(typeof(int));

    var expression = Expression.Lambda<Func<int, int, int>>(
        Expression.Multiply(
            Expression.Call(first.GetMethodInfo(), firstParam, secondParam),
            Expression.Call(second.GetMethodInfo(), firstParam, secondParam)),
        firstParam,
        secondParam);

    return expression.Compile();
}

Also, you could replace the Delegate with Func<int,int,int> in the method signature so the invocation of the result will be faster and invocation of the Combine method itself - typesafe.

Keep in mind, though, that delegates obtained in such a way are better to be cached, otherwise the overhead of compiling lambda's will be significant.

Another approach, the simple and the less performant one is:

static Delegate CombineSimple(Delegate first, Delegate second)
{
    return new Func<int, int, int>(
        (firstParam, secondParam) => 
            (int)first.DynamicInvoke(firstParam, secondParam) *
            (int)second.DynamicInvoke(firstParam, secondParam));
}

Upvotes: 2

Related Questions