Particulars about Action delegate in C# - c#

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.

Related

C#: List of functions with variable number of arguments

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.

C# lambda convert

Hello I am trying to create a filter-system for list's.
public void filter<T, E>(String fieldName, List<T> list, Func<T, E> rule)
{
IList<FilterDto> filters = GetFilter(fieldName);
foreach (FilterDto filter in filters)
{
if (filter != null)
{
if (filter.valueType == ValueType.NUMERIC)
{
list.Remove( this.filter(fieldName, Convert.ToDouble( o => rule(o) ) ) );
}
else if (filter.valueType == ValueType.DATE)
{
}
else if (filter.valueType == ValueType.TEXT)
{
}
else
{
Log("Unkown filter comparsion");
}
}
}
}
On this line:
list.Remove( this.filter(fieldName, Convert.ToDouble( o => rule(o) ) ) );
I get the error message:
Error CS1660: Cannot convert lambda expression to type 'bool' because it is not a delegate type
I have would do the real filtering on the methods something like that:
public bool filter(String fieldName, double? value)
public bool filter(String fieldName, int? value)
public bool filter(String fieldName, Date? value)
The bottom line is no overload of Convert.ToDouble() takes a lambda expression as an argument. The compiler is basically picking one of the overloads -- in this case the one that takes a bool -- and telling you it can't convert the lambda into a bool.
Are you trying to pass the return value from rule() to be converted? If so, just call rule() itself, and pass it whatever var you need to pass it (unclear from your question):
list.Remove( this.filter(fieldName, Convert.ToDouble(rule(yourVar))));
What you do does not make much sense. In your comedy (or tragedy - you choose) you have the following actors:
An IList<FilterDto>, the container of your filter objects.
The filter method who keeps everyone together.
A filter local variable who owes his existance to (1) and holds a grudge against (2), because it has the same name.
The Convert.ToDouble method who is a bit of a diva because it won't just accept anyone as its parameter's argument.
The Remove method, son of (1).
The o => rule(o) lambda expression.
Enter the IList (1). You iterate over it and create the filter (3) variable. Now comes the Remove method (5) which you call, probably to remove said filter (3), which you don't actually do; instead you remove the result of the filter method (2), which is unfortunate, because filter (2) does not have a result (alas it is void). However, filter(2) wants a Func<T, E> as its second argument (although not necessarily the same T and E as the original call to filter - the method). In comes the evil ToDouble (4), which has a result of double, which is not a Func<T, E> - hence your error. To make things worse, a o => rule(o) (6) makes its way into ToDouble's (4) argument list. This now is a Func<T, E>, although ToDouble (4) won't be able to do much with it, because even if it tries hard, it can't convert it into a double.
Now how to we cut this Gordian Knot?
Well, as I see it you might want to remove an item from the IList (1) in case a subsequent call to your filter rule is successful. My best guess (it has to be a guess because your question is not quite clear there) is that you intent something close to this:
T[] itemsToRemove = list.Where( o => rule(Convert.ToDouble(o)) ).ToArray();
foreach (T item in itemsToRemove) {
list.Remove(item);
}
I found my mistake... I have to use RemoveAll.
Like that:
list.RemoveAll(o => this.filter(filter, Convert.ToDouble((rule(o) as Double?))));

Linq .Select() / .SelectMany() automatically uses second, optional parameter

I just found the weirdest behavior in Linq:
When calling unary functions I like to just pass the function name, so instead of
var foo = myList.Select(item => MyFunc(item));
I write
var foo = myList.Select(MyFunc);
which should be the same. Only in some cases, it isn't! Namely if the function has a second parameter which is an int and optional:
private string MyFunc(string input, int foo = 0)
{
...
}
In this case, the statement
var foo = myList.Select(MyFunc);
equals
var foo = myList.Select((item, index) => MyFunc(item, index));
If the second parameter is either not opional or not an int, the compiler complains, but in this case, it just sneakily surprises you.
Has anyone else encountered this? Which other Linq expressions work this way? (so far, .SelectMany() does). And what is the most elegant way to work around this behavior (and keep others from falling into the same trap?)
This is not really an issue of specific LINQ extension method, but how optional parameters are handled for Funcs and Actions, in short - they are not, they are considered a regular parameter and default value is omitted when selecting a corresponding Func/Action signature. Take a look here Optional Parameters, No overload for 'Employee' matches delegate 'System.Func<Employee> or here Invoke Func<T1, T2, T3> which has optional parameters?.
In other words, your MyFunc cannot be used as Func<string, string>, you must use Func<string, int, string>, which in case of Select happens to be present as an overload with index added.

How to make a function private to a method?

I'm working on a method that needs to repeat a small operation at different spots, but the code to be repeated should be private to the method. The obvious solution is a nested function. Whatever I try however, the C# compiler barfs at me.
Something roughly equal to this Perl snippet:
my $method = sub {
$helper_func = sub { code to encapsulate };
# more code
&$helper( called whenever needed );
# more code
}
is what I am talking about, and what I'm trying to accomplish in C#.
No other method in the class should be able to access the helper function in this context. The most logical means of writing this construct in C#, as it appears to me would be something like this:
var helper = (/* parameter names */) => { /* code to encapsulate */ };
And actually make the compiler earn its keep.
Since such an assignment is forbidden, as is the equivalent using the older delegate(){} syntax in place of the lambda, and so is declaring a delegate type within a method—what csc actually allows me to write however, is this:
private delegate /* return type */ Helper(/* parameters */);
private /* return type */ method(/* parameters */) {
Helper helper = (/* parameter names */) => {
/* code to encapsulate */
};
// more code
helper( /* called whenever needed */ );
// more code
}
Which is all fine and dandy for not copy and pasting a chunk of code around and editing the parameters by hand but it leaks a private delegate type to the rest of the class rather than keeping it private to the method. Which defeats the purpose in the first place. Using goto statements and local variables for parameters would provide better encapsulation of "helper" in this context without sacrificing code reuse. If I wanted to simulate function calls by passing parameters through registers, I think would rather use an assembler. I haven't found an acceptable way of refactoring the code to avoid the problem altogether either.
So, is it even possible to force this Common Object Oriented Language to obey?
You actually can do this in C#.
Func<T1, T2, ..., TReturn> myFunc = (a, b, ...) =>
{
//code that return type TReturn
};
If you need an anonymous method of return type void use Action instead of Func:
Action<T1, T2, ...> myAction = (a, b, ...) =>
{
//code that doesn't return anything
};
If you are in C# 3.5 or higher you can take advantage of the lambdas and convenience delegate declarations Func<> and Action<>. So for instance
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
The reason you can't do
var addOne = (ii) => ii +1;
is because of Homoiconicity, the lambda can be interpreted as two different constructs, a delegate and an expression tree. Thus the need to be explicit in declaration.
If you explicitly type it, it will work, i.e.
Action<paramType1, paramType2> helperAction = (/* parameter names */) => { /* code to encapsulate */ };
Func<paramType1, paramType2, returnType> helperFunction = (/* parameter names */) => { /* code to encapsulate */ };
The reason var doesn't work is that a lambda expression can evaluate to multiple types (I believe either a delegate or expression tree, but don't quote me on that) and the compiler in this situation is unable to infer which was meant.
I recommend looking at the Action<T> and Func<TResult> delegates and their overloads. You can do something like this
static void Main(string[] args)
{
SomeMethod();
}
private static void SomeMethod()
{
Action<int> action = (num) => Console.WriteLine(num);
Enumerable.Range(1,10).ToList().ForEach(action);
Console.ReadKey();
}
Here SomeMethod is private and has a local Action<int> delgate that takes an int and does something to it.
I think the issue that you came across is that you can't use implicit typing (i.e. use var) when assigning a lambda expression to a variable.
You can't use the var keyword with lambdas or delegates because they both require additional context information (delegates require a return type, and lambdas require a return type and parameter types). For instance, the (params) => { code } syntax requires to be able to infer the parameter types and return types to work: you do this by explicitly giving it a type.
The generic System.Action delegate type (returns void) could do a good job at what you're trying:
Action<ArgumentType1, ArgumentType2, ...> myDelegate = (params) => { code };
Otherwise, there's also the System.Func, which has a return type, that must be passed as the last generic argument.
It depends on what your definition of hiding is.
The func/action solution (like the one Scott suggests)
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
Feals like hidding the method definition when writing regular C# code BUT is when looking at the IL equivalent of
//This is pseudo code but comes close at the important parts
public class Class1
{
//The actual type is different from this
private static Func<int, int> myMethod = AnonymousFunction;
public void f()
{
myMethod(0);
}
private static int AnonymousFunction(int i)
{
return 1;
}
}
So if you really want to get to the method from outside of the one "hidding" it you can do this with reflection The actual name generated for the field storing the delegate is illegal in C# bul valid in CLR context but that's the only thing that stand in the way of using the delegate as a regular delegate stored in a field (that is if you figue out the name :) )
It's quite simple actually. As the Method seems to have another responsibility than your current Class (why else would you hide this method) move your method into it's own Class and the part you want to have private into a private method in the new class.

Get Method Name Using Lambda Expression

I'm trying to get the name of a method on a type using a lambda expression. I'm using Windows Identity Foundation and need to define access policies with the type name with namespace as a resource and the method name as the action. Here is an example.
This is the type I would be getting the type name and method name from:
namespace My.OrderEntry {
public class Order {
public void AddItem(string itemNumber, int quantity) {}
}
}
This is how I would like to define the access policy through a DSL:
ForResource<Order>().Performing(o => o.AddItem).AllowUsersHaving(new Claim());
From that statement, I would like to get "My.OrderEntry.Order" as the resource and "AddItem" as the action. Getting the type name with namespace is no problem, but I don't think I can use a lambda for a method like I'm trying to do.
public static IPermissionExp Performing<T>(
this IActionExp<T> exp,
Func<T, delegate???> action) {} //this is where I don't know what to define
Is this sort of thing even possible to do? Is there another way to do this sort of thing without using magic strings?
There are two ways to do this:
1: You could make overloads that take the various Func and Action delegates(eg Expression<Func<T, Func<TParam1,TParam2, TReturn>>. Note that your callers would need to specify the generic parameters explicitly, either in the method call or by creating the delegate. This would be used like this:
ForResource<Order>().Performing(o => new Action<string>(o.AddItem)).AllowUsersHaving(new Claim());
2: You could take an Expression<Action> that contains a method call, and parse out the MethodInfo being called from the expression tree. This would be used like this:
ForResource<Order>().Performing(o => { o.AddItem(null); }).AllowUsersHaving(new Claim());
It looks like this is what you are looking for if you want the name of the action delegate method passed in to the Performing function.
public static IPermissionExp Performing<T>(
this IActionExp<T> exp,
Expression<Action<T, string, int>> action)
{
var expression = action.Body as MethodCallExpression;
string actionMethodName = string.Empty;
if (expression != null)
{
actionMethodName = expression.Method.Name;
}
// use actionMethodName ("AddItem" in the case below) here
}
This would allow you to call the method like this...
ForResource<Order>().Performing((o, a, b) => o.AddItem(a, b)).AllowUsersHaving(new Claim());
I recently did a thing at work where you defined the a method using a lambda, which the internal object then took the name of. You could use strings as well, or pass in a MethodInfo but the first one isn't really type safe (and typos are a big risk), and the latter is not very elegant.
Basically I had a method like this (this is not the exact method, it is a bit more advanced):
public void SetRequest(Request req, Expression<Func<Service, Func<long, IEnumerable<Stuff>>> methodSelector);
The key here is the "Expression" thing, this lets you "select" a method like this:
SetRequest(req, service => service.SomeMethodTakingLongReturningStuffs);
Method selector is made into a expression tree which you can then fetch different bits of data from. I don't recall exactly what the resulting tree looks like, it also depends on how your lambdas look.
You could pass it in as a Action instead, which doesn't force any return type. It is still a little messy though, because you have to pass some arguments to the method in order for it to compile.

Categories