Can you link the result of one delegate as the input of another in C #?

I am looking for a way to link several delegates so that the result from one becomes the contribution of the next. I am trying to use this in an equation solving program where parts are executed by different methods. The idea is that when you build an equation, the program adds delegates and ties them in a specific order, so it can be solved correctly. If there is a better way to approach the problem, please share it.

+3
c # chaining delegates
Jan 04 2018-12-12T00:
source share
5 answers

This can help:

public static Func<T1, TResult> Compose<T1, T2, TResult>(Func<T1, T2> innerFunc, Func<T2, TResult> outerFunc) { return arg => outerFunc(innerFunc(arg)); } 

This performs the function composition function , by running innerFunc and passing the result to outerFunc when the original argument is provided:

 Func<double, double> floor = Math.Floor; Func<double, int> convertToInt = Convert.ToInt32; Func<double, int> floorAndConvertToInt = Compose(floor, convertToInt); int result = floorAndConvertToInt(5.62); Func<double, int> floorThenConvertThenAddTen = Compose(floorAndConvertToInt, i => i + 10); int result2 = floorThenConvertThenAddTen(64.142); 
+7
Jan 04 2018-12-12T00:
source share
— -

Yes, it is possible - you need to make sure that the return type of the delegate is the parameter type of the called delegate.

Many LINQs are built this way, although you can take a look at the expressions.

+3
Jan 04 2018-12-01T00:
source share

The type of API you are describing is called the Fluent API . Take a look at the previous article for a good tutorial.

Regarding the delegation chain, take a look at the LINQ extension methods in .NET 3.5, in particular, how the lambda function passed (delegates) as a result get an IEnumerable result, which can then be bound to another + lambda extension method.

In your particular case, you may need to create a class called Functor to accept a delegate and return another Functor, which can also be managed by delegates.

Respectfully,

0
Jan 04 2018-12-12T00:
source share

using GetInvocationlist, you can achieve this.

  Delegate[] chain = chained.GetInvocationList(); int res = 10; for( int i = 0; i < chain.Length; i++ ) { //Call chain[i] res = chain[i](res); } 
0
Jan 04 2018-12-14T00:
source share

I myself worked on a similar problem, which included calling a sequence of delegates and passing the output of one delegate to the next (etc.), so I thought you might be interested to see the code that I developed as a proof of concept:

 static class Program { private static IList<Func<int, int>> delegateList = new List<Func<int, int>>() { AddOne, AddOne, AddOne, AddOne, AddOne, AddOne, AddOne, AddOne, AddOne, AddOne, }; static void Main(string[] args) { int number = 12; Console.WriteLine("Starting number: {0}", number); Console.WriteLine("Ending number: {0}", delegateList.InvokeChainDelegates(number)); Console.ReadLine(); } public static int AddOne(int num) { return num + 1; } public static T InvokeChainDelegates<T>(this IEnumerable<Func<T, T>> source, T startValue) { T result = startValue; foreach (Func<T, T> function in source) { result = function(result); } return result; } } 

The sequence should contain delegates of the same type, so it is not as powerful as the already accepted answer, but with several settings, both bits of code can be combined to provide a powerful solution.

0
Nov 28 '12 at 20:24
source share



All Articles