Is it possible in C# to have higher-order function which takes a function with an arbitrary number and type of arguments and return values, e.g.,
// No valid C# code
void MyFunction(Func f)
{
// do something
}
MyFunction(string.Join); // type: Func<String, IEnumerable<String>, String>
MyFunction(string.CompareTo); // type: Func<object, int>
// ...
I guess, this question really boils down to whether there's a most generic type for functions which can hold any function with possibly different number and type of arguments.
My use-case is the following: I have a method which takes a MethodInfo object. Currently, I do something like
DoSomething(((Func<object, int>)string.CompareTo).Method)
However, I'd have to repeat this for every different kind of function I expect. I'd prefer a solution in which DoSomething could by itself determine the type, so I just give it the Function itself instead of the MethodInfo object.
EDIT:
To be more precise, I'm writing a Linq-To-X provider using ReLinq. I got some example code from a tutorial blog on this topic (https://www.codeproject.com/Articles/42059/re-linq-ishing-the-Pain-Using-re-linq-to-Implement and https://weblogs.asp.net/dixin/understanding-linq-to-sql-10-implementing-linq-to-sql-provider). For eager execution functions like Sum or Count, I need to wrap them into a MethodCallExpression object.
In the example code, it is solved like this:
public static IQuery CountToSql<T>(this IQueryable<T> source)
{
ArgumentChecker.CheckNull(source, nameof(source));
var expression =
Expression.Call(
null,
GetMethodInfo(Queryable.Count, source),
new Expression[] { source.Expression }
);
return ToQuery(expression, ((DbQueryable<T>)source).SyntaxProvider);
}
private static MethodInfo GetMethodInfo<T1, T2>(Func<T1, T2> f, T1 unused1 => f.Method;
private static MethodInfo GetMethodInfo<T1, T2, T3>(Func<T1, T2, T3> f, T1 unused1, T2 unused2) => f.Method;
// ...
However, I don't want to write this for every type of function (e.g., Queryable.Sum, Queryable.Count, ...). The current solution necessitates it. I just want one single method that can handle all, as they look the same for 90%.
It seem strange that you need to call such different delegates from one place.
I think you need something like "EventDispatcher", when your code got data that should be then casted to object, but after that inside a call you want to operate a real objects.
If I wrong please tell more about task.
If I right, you have to replace reflections by generics. Create method that will wrap you delegate by Action.
public Action<object> WrapCall<T, K>( Func<T, K> func)
{
return (data) => func((T)data);
}
public Action<object, object> WrapCall<T1, T2, K>(Func<T1, T2,K> func)
{
return (t1Data, t2Data) => func((T1)t1Data, (T2)t2Data);
}
and so one.
It may be not solve your problem but will helps you to find solution in other way.
Related
I've occured the following code:
public static class FuncUtils
{
public static Func<T1, T3> Compose<T1, T2, T3> (Func<T1, T2> f1, Func<T2, T3> f2)
{
return a => f2(f1(a));
}
}
What's the biggest mystery for me is this one
return a => f2(f1(a));
Can you explain how does it work?
It will return a Func<T1, T3>, that is a function (delegate) that takes some parameter of type T1 and returns a result of type T3 . Let's call the returned Func f
The result (returned value) of f is just the result from the 2 function parameters f1 and f2 composed (as in math function composition) on any parameter given.
More on f, the returned Func:
Apply f1 on the parameter a (of type T1), get some result b (of type T2), then apply f2 on b , call this result c (of type T3). c will be the result for any a passed to f .
You need to understand the concept of higher order functions to make sense of the above method. Higher order functions are modeled as delegates in .NET and therefore in c#. A delegate is a data type that represents a method to be called. So you when you execute your method, the result you get is another method that you need to call to get your result (hence higher order function).
So let's dissect your method:
The parameters Func<T1, T2> f1 and Func<T2, T3> f2 are delegates, which each represent a method. You can call these methods by calling the delegates:
//You need a value of type T1, here represented by the variable a
T2 value = f1(a);
The call must look like this, because this is how the delegate id defined:
public delegate TResult Func<T, TResult>(T item);
You can call f2 like you call f1, just with a different parameter type. Since T2 is the return of f1 and the parameter of T2, you can just pass the result of f1 to f2:
T2 result = f2(value);
Or inline:
T2 result = f2(f1(a));
You will find this in your method, which means it performs a nested call of the two methods.
In a special twist, Compose does not call the methods and return the result, it returns a higher order function by itself. It uses the lambda operator => for this, which is another way to create a delegate. To the left of the lambda operator is a, which is an arbitrary name for the new function's parameter. The type of a is T1, which the compiler can figure out by type inferrence.
So in the end the caller has to execute the returned delegate to get the final result. This is called defered execution and is commonplace in LINQ.
You can think of thw Compose method of a way to nest the call to two methods before you actually make the call.
Sorry for this question: I am somehow new to lambda expressions.
I have a library and some functions and I want to pass the to execute some actions. Therefore I thought about putting some code in a lamba expression, associate it to a variable and the make it execute from the library s/r.
In short (pseudocode):
var1 = { ...code1...};
var2 = { ...code2...};
ExternalFunction(??? var1, ??? var2);
ExternalFunc(??? var1, ???var2)
{
Console.WriteLine("Executing code 1");
???
Console.WriteLine("Executing code 2");
???
}
Depending on what your code should do you will need a parameter of type Action<T1, T2, ...> or Func<T1, T2, ...>. However you cannot create your method so that it runs any arbitrary code, you have to provide a return-type and the parameters of course.
So if your code of block returns an int and expects a string you may write this:
Func<string, int> myFunc = x => Convert.ToInt32(x) + 1;
void ExternalFunc(Func<T1, T2> myFunc, T1 param) {
var myInt = myFunc(param);
}
Now call it like this:
ExternalFunc(myFunc, "1");
However you cannot expect this code to run also:
Func<int> myOtherFunc = () => 1;
ExternalFunc(myOtherFunc)
because myOtherFunc must be of type Func<T1, T2>, not just Func<T> to be passed to ExternalFunc.
Moreover if your code-block should not return anything (void), use an Action<...> instead of Func<...>.
Well, here's your standard documentation for lambdas:
https://msdn.microsoft.com/en-us/library/bb397687.aspx?f=255&MSPPError=-2147217396
if you're looking for the type inference of a lambda, it's a Func. So the parameter text you're looking for is probably this:
public void youtExternalFunction(Func<> var1, Func<T, U> var2)
How can I create a Delegate with types only known at run time ?
I would like to do the following :
Type type1 = someObject.getType();
Type type2 = someOtherObject.getType();
var getter = (Func<type1, type2>)Delegate.CreateDelegate(
typeof(Func<,>).MakeGenericType(type1, type2), someMethodInfo);
How can I achieve something similar ?
I suspect you want Expression.GetFuncType as a simpler way of doing your typeof(...).MakeGenericType operation.
var delegateType = Expression.GetFuncType(type1, type2);
Delegate getter = Delegate.CreateDelegate(delegateType, someMethodInfo);
You can't have a compile-time type for getter that's more specific than Delegate though1, because you simply don't know that type at compile-time. You could potentially use dynamic though, which would make it easier to invoke the delegate:
dynamic getter = ...;
var result = getter(input);
1 As noted in comments, you could cast to MulticastDelegate, but it wouldn't actually buy you anything.
You could create a generic method for that:
public Func<T1, T2> GetFunc<T1, T2>(T1 Object1, T2 Object2, MethodInfo Method)
{
return (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<,>).MakeGenericType(typeof(T1), typeof(T2)), Method);
}
And I bet you can do something using the same philosophy with the Method to avoid all this reflection stuff.
Obs: that would work only if T1 and T2 are typed variables. If they are as object you'll get a Func<object, object>. But....if the objects you will give to the method are as object as well, that would be no problem at all.
And maybe you can even use Func<object, object> always, depending on your scenario.
I'm a bit fuzzy on the new Action/Func/Variance/CoVariance stuff, which is probably what I need.
What I want is to be able to pass a delegate as a parameter to a method, that takes a string and returns a bool. The problem is that I can't use a typed delegate or interface since it will be used in different libraries which doesn't share libraries, and both will be invoked by a third.
So in general I want the delegate to be inferred by it's input and returning type.
So it'll be like:
delegate bool IncludeItemDelegate(string item);
ClassA.FetchItems(int someParameter,includeItemDelegate);
ClassB.FetchItems(int someParameter,string someOtherParam,includeItemDelegate);
Where A and B doesnt share any libraries, can it be done?
How about Func<string,bool> ?
Predicate is built-in and also signals intent:
ClassA.FetchItems(int someParameter, Predicate<string> filter);
It's also possible to pass the Predicate as a lambda
class A
{
static public IEnumerable<string> FetchItems(int max, Predicate<string> filter)
{
var l = new List<string>() {"test", "fest", "pest", "häst"};
return l.FindAll(filter).Take(max);
}
}
like this
var res = A.FetchItems(2, s => s.EndsWith("est"));
1) What is the real definition for Action delegate? some definitions describe it is as polymorphic conditional map , some say it *Applied decision Table *.
(You may ask what will you achieve by knowing definition , if i know it i can understand its real purpose).
2) Thanks Binary Worrier,Andrew Hare of stackoverflow for giving nice examples.
When i declare
string[] words = "This is as easy as it looks".Split(' ');
`Array.ForEach(words, p => Console.WriteLine(p));`
i can understand what it actually does.But when i declare ,How does C# interpret when i
declare
Dictionary<SomeEnum, Action<User>> methodList =
new Dictionary<SomeEnum, Action<User>>()
methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse);
Does it store collections of Actions in dictionary ?.unfortunately as the example was incomplete i did not get it.
3) What is the functional difference between Action , Function ,Predicate delagets?
It's just another delegate. Action<T> is declared like this:
void Action<T>(T item)
It's just "something which acts on a single item". There are generic overloads with more type parameters and normal parameters. In itself, an Action<T> isn't an applied decision table or anything like that - it's just a delegate which can do "something" with an item.
The dictionary example is just a dictionary with enum values as keys, and actions as values - so you can look up what to do based on the enum value, and then pass in a User reference for it to act on.
As for Func vs Action vs Predicate: Func is like Action, but returning a value. Predicate is similar, but always returns bool, and there aren't the range of generic overloads, just Predicate<T> to determine if an item "matches" the predicate.
Action, Func and Predicate have different signatures:
void Action<...>(...)
T Func<..., T>(...)
bool Predicate<T>(T)
Action<...> is the same as Func<..., void>
Predicate<T> is the same as Func<T, bool>
1) the Action delegates
(Action, Action<T>, Action<T, T2> ...)
are general purpose delegate to avoid the creation of to many delegate in your application. The idea is :
//- Action => void method with 0 args
//- Action<T> => void method with 1 arg of type T
//- Action<T, T2> => void method with 2 args of type T et T2
//...
2) that dictionary stores for each 'SomeEnum' values, a method wicth match this signature :
void MethodExample (User arg);
Here is an example :
public Init() {
deleteUserMethodsByStatus = new Dictionary<SomeEnum, Action<User>>();
deleteUserMethodsByStatus.Add(UserStatus.Active, user => { throw new BusinessException("Cannot delete an active user."); });
deleteUserMethodsByStatus.Add(UserStatus.InActive, DoUserDeletion});
}
//This is how you could use this dictionary
public void DeleteUser(int userId) {
User u = DaoFactory.User.GetById(userId);
deleteUserMethodsByStatus[u.Status](u);
}
//the actual deletion process
protected internal DoUserDeletion(User u) {
DaoFactory.User.Delete(u);
}
3) Difference between Action , Function ,Predicate :
- an action is a void method(no return value)
- a function is a non void method (has a return value)
- a predicate must return a boolean value and take 1 argument (it basically answere yes or no to question that take 1 argument)
I hope this help.