Func Delegate vs Function - c#

Can someone tell me the advantages of using a delegate as opposed to calling the function itself as shown below (or in other words why choose Option A over Option B)? I was looking at someone's linq code last night and they had something similar to Option A but it was being used to return a compiled linq query.
I realize the former can now be passed around to other functions.. just not sure of its practicality. BTW, I realize this wouldn't compile as-is.. uncommented one of the functions before posting. TYIA
class Program
{
static void Main(string[] args)
{
Console.WriteLine(SayTwoWords("Hello", "World"));
Console.ReadKey();
}
// Option A
private static Func<string, string, string>
SayTwoWords = (a, b) => String.Format("{0} {1}", a, b);
// Option B
private static string SayTwoWords(string a, string b)
{
return String.Format("{0} {1}", a, b);
}
}
************EDIT************
Not sure if it explains my question better but here is an example of the type of code that originally got me thinking about this:
public static class clsCompiledQuery
{
public static Func<DataContext, string, IQueryable<clsCustomerEntity>>
getCustomers = CompiledQuery.Compile((DataContext db, string strCustCode)
=> from objCustomer in db.GetTable<clsCustomerEntity>()
where objCustomer.CustomerCode == strCustCode
select objCustomer);
}
Is there any advantage to writing a function in this way?

There is no advantage in the code you posted. In your code, using the delegate just adds complexity as well as an extra runtime cost - so you're better off just calling the method directly.
However, delegates have many uses. "Passing around" to other methods is the primary usage, though storing a function and using it later is also very useful.
LINQ is built on top of this concept entirely. When you do:
var results = myCollection.Where(item => item == "Foo");
You're passing a delegate (defined as a lambda: item => item == "Foo") to the Where function in the LINQ libraries. This is what makes it work properly.

A very useful function of delegates is that you can send them wherever you want. It's like having your function everywhere you need it. A big use for this is event handling. Say you have a button, and when a user clicks this button you want any number of functions to be called. If you think about this there are a couple of ways you could do this:
You Could:
Call a function that calls each other function you want called.
This means that for each new function you want to be called, you must hard code it into this function. Very annoying.
OR
You could have a public list of the names of each function you want to call (delegates), and anyone can add or remove these functions at any time without the owner of the click event having to know or even do any work regarding any of them. When the click event happens, every event in the list is called and sent the same parameters, and you're done.

It's only useful if you have to pass the delegate around. If you can resolve the function at compile time, it's less useful.

With the static method you have to pass in all the variables needed.
With the delegate you could inline your implementation and have access to the variables in scope.

you can use delegates as "function pointers", so you can give the functions or "actions" to other functions to execute.
what also would be interesting with delegates is the possibility of "precompiling", like you "build" a new function and then return this function to your application

// Option A
private static Func<string, string, string>
SayTwoWords = (a, b) => String.Format("{0} {1}", a, b);
// Option B
private static string SayTwoWords(string a, string b)
{
return String.Format("{0} {1}", a, b);
}
In the above case, Option B is what I would go with, unless I need functionality of SayTwoWords to be changed. In the case of Option A, SayTwoWords can be assigned a different function. Catch more detailed differences in this answer:
There is a situation where Option A makes sense. Consider a case where you have to compile an expression to a delegate. Since compiling expression is heavy, that's something you would want to do it only once. A pattern like this helps:
public static class Cache<T>
{
public static readonly Func<T> Get = GetImpl();
static Func<T> GetImpl()
{
//build expression and return compiled delegate
}
}
instead of
public static class Cache<T>
{
public static T Get()
{
//build expression, compile delegate and invoke the delegate
}
}
In the first case when you call Get, GetImpl is executed only once, where as in the second case, (expensive) Get will be called every time.

Related

Delegate chain method results to function body

Trying to build a formatting delegate/function. It's mainly for printing exercise results.
I am trying to access the result of a argument but I think my understanding of delegates is still kind of bad. The method is invokable in the block itself but I would like the result, currently it prints the result definition.
System.Func2[ConsoleApp1.LoanQueries,System.Collections.Generic.IEnumerable1[System.Decimal]]
Below is the code that will create to result to parse, the parsing method and a code snippet that I based my code on.
My questions are:
Is this possible or am I breaking some rules?(trying to use expressions/functional)
Is it possible to declare just a delegate instead of the function(This would probably involve formatting every time instead of the function.)
Create data to format
// Method bodied expression
public IEnumerable<decimal> LoanQueryBodied =>
from amount in LoanAmounts
where amount % 2 == 0
orderby amount ascending
select amount;
// Query expression:
public IEnumerable<decimal> LoanQueryExpression () =>
LoanAmounts
.Where(a => a % 2 == 0)
.OrderBy(r => r);
Method for data and final formatting
public static void FormatLoans<TObject>(
Func<TObject> instance,
Func<TObject, IEnumerable<decimal>> function)
{
// This is the function object but should be IEnumerable<decimal> result passed down.
// Just like TObject is passed , but how?
Console.WriteLine(string.Join(" - ",function));
}
Use method
LoanQueries.FormatLoans<LoanQueries>(() =>
new LoanQueries()
, inst => inst.LoanQueryBodied);
LoanQueries.FormatLoans<LoanQueries>(() =>
new LoanQueries()
, inst => inst.LoanQueryExpression());
Code that I based it loosely on
public static class Disposable
{
public static TResult Using<TDisposable, TResult>(
Func<TDisposable> factory,
Func<TDisposable, TResult> map)
where TDisposable : IDisposable
{
using (var disposable = factory())
{
return map(disposable);
}
}
}
Example invoked
var time= Disposable
.Using(
() => new WebClient(),
client => XDocument.Parse(client.DownloadString("http://time.gov/actualtime.cgi")))
.Root
.Attribute("time")
.Value;
I would like to chain my method like this but if this is not possible or bad practice I would also like to know.
You need to call function and instance using ():
Console.WriteLine(string.Join(" - ",function(instance())));
And apparently you want to return the string, rather than printing it, to allow chaining, so:
public static string FormatLoans<TObject>(
Func<TObject> instance,
Func<TObject, IEnumerable<decimal>> function) =>
string.Join(" - ",function(instance()));
However, I think you are really over-complicating/over-generalising this. Your method is not nearly as general as the Disposable.Using method you showed. Your method could just be declared like this:
public static string FormatLoans(IEnumerable<decimal> loans) =>
string.Join(" - ", loans);
Callers:
LoanQueries.FormatLoans(new LoanQueries().LoanQueryBodied)
LoanQueries.FormatLoans(new LoanQueries().LoanQueryExpression)
Disposable.Using uses delegates because it is trying to recreate the using statement. The second argument must be evaluated inside the using statement, so that any exceptions thrown lead to the disposal of the IDisposable, which is why it has to be wrapped up in a delegate. If not, the second argument would be evaluated before the Using method runs, and that misses the whole point.
However, your method does not have special requirements like that, so you don't need delegates.

IEnumerable.Select() for a single item

I recently created this extension method:
public static TR Calculate<TS, TR>(this TS item, Func<TS, TR> selector)
=> selector(item);
Then, I am able to refactor this ugly code, from:
int value = panel.Controls.Cast<Control>().Last().Location.Y
+ panel.Controls.Cast<Control>().Last().Size.Height;
to:
int value = panel.Controls.Cast<Control>().Last().Calculate(
o => o.Location.Y + o.Size.Height);
I would like to know if there is a way to do this using built in .NET functions instead?
By "innate", I guess you mean you don't want to any new methods yourself?
Well, you can do something like this:
value = ((Func<InputType, OutputType>)(o => o.First + o.Second + o.Property.Value))(collection[calc(param)]);
Basically, casting the lambda to a delegate type and then calling the delegate.
Or maybe I have overcomplicated this. What you actually want might toto just not write collection[calc(param)] that many times. If that's the case, you can just:
var o = collection[calc(param)];
value = o.First + o.Second + o.Property.Value;
I don't see why you can't do it like that.
I really suggest you write a separate a method for this kind of transformation. It will be much more readable.
// name this properly so that it describes what you actually want.
public OutputType TransformCollectionItem(TInput o) {
return o.First + o.Second + o.Property.Value;
}
I'm going to say that you shouldn't do that - I don't think it really makes the code more readable.
Given the original code:
int value = panel.Controls.Cast<Control>().Last().Location.Y
+ panel.Controls.Cast<Control>().Last().Size.Height;
Your extension method lets you do this:
int value = panel.Controls.Cast<Control>().Last().Calculate(
o => o.Location.Y + o.Size.Height);
But there seems to be very little advantage over doing this instead:
var c = panel.Controls.Cast<Control>().Last();
int value = c.Location.Y + c.Size.Height;
The latter is actually shorter, and doesn't require the reader to know about an extension method.
Also, your extension method will appear in the tooltip for EVERYTHING...
Mind you, it does allow some interesting code such as
double negated = 1.0.Calculate(x => -x);
The operation you're describing here is usually called "apply", since it is simply applying a function to an argument as an extension method. You ask for a way to do it "innately"; I'm not quite sure what you mean. Function application is already innately built into the syntax of C#. To apply a function F to an argument a to get a result r in C# you do it like this:
r = F(a)
So in your case you would assign the lambda to a variable and then apply it, or, as the other answer notes, cast it to the appropriate function type and apply it.
If you want function application as an extension method that takes a lambda, you'll have to write it yourself.
What you are effectively calling out here is that "let expressions" are missing from C#. What I would really want to write here is:
int value =
let o = panel.Controls.Cast<Control>().Last() in
o.Location.Y + o.Size.Height;
Which many languages support, but C# only supports in query comprehensions.
See my answer to this question for more on "let expressions" in C# and why they would be useful, and how they are equivalent to your application function: DRY (Don't Repeat Yourself) and if assignements
Incidentally, if you name your method Select and make a double-application version called SelectMany, then you can use LINQ on... well, anything:
using System;
static class X
{
public static R Select<A, R>(this A item, Func<A, R> selector) =>
selector(item);
public static R SelectMany<A, B, R>(this A item, Func<A, B> toB, Func<A, B, R> toR) =>
toR(item, toB(item));
}
public class P
{
public static void Main()
{
string myString = "hello";
string result = from s in myString
from b in s + "goodbye"
select b.ToUpper() + " " + s;
Console.WriteLine(result);
}
}
That is a bizarrely baroque way to write a simple program, but if you are really bent on making extension methods that do things that are already in the language, you can do it!
Exercise: Implement the identity monad. You are well on your way!

Is there a technique for using DebugFormat() with args that are expensive to construct?

I'm a big fan of log4net and log4j's "format" API for logging messages, which avoids the cost of calling ToString() on arguments if the necessary log level is not enabled.
But there are times when one or more of the arguments I'd use is not a simple object, it needs to be constructed in some way. For example, like this:
logger.DebugFormat("Item {0} not found in {1}",
itemID,
string.Join(",", items.Select(i => <you get the idea>))
);
Is there a technique to encapsulate the second argument (the Join expression) such that it won't be executed unless DebugFormat decides that it should be (like it does for the ToString of the first argument)?
It feels like a lambda or func or something should be able to help here, but I'm fairly new to C# and I can't quite put my finger on it.
You can create extension method or wrapper class, but it's not easy to get satisfying syntax, because you want some parameters (itemID in your example) to be stated explicitly, and some to be resolved only if necessary. But you cannot pass anonymous function as object. Instead I'd use another solution which does not require extension methods or wrappers. Create class like this:
public sealed class Delayed {
private readonly Lazy<object> _lazy;
public Delayed(Func<object> func) {
_lazy = new Lazy<object>(func, false);
}
public override string ToString() {
var result = _lazy.Value;
return result != null ? result.ToString() : "";
}
}
This accepts function which returns object in constructor and will not call this function until ToString() is called, which as you know is called by log4net only if necessary (if such debugging level is enabled). Then use like this:
logger.DebugFormat("Item {0} not found in {1}",
itemID,
new Delayed(() => string.Join(",", items.Select(i => <you get the idea>)))
);

How to pass a predicate as parameter c#

How can I pass a predicate into a method but also have it work if no predicate is passed? I thought maybe something like this, but it doesn't seem to be correct.
private bool NoFilter() { return true; }
private List<thing> GetItems(Predicate<thing> filter = new Predicate<thing>(NoFilter))
{
return rawList.Where(filter).ToList();
}
private List<thing> GetItems(Func<thing, bool> filter = null)
{
return rawList.Where(filter ?? (s => true)).ToList();
}
In this expression s => true is the fallback filter which is evaluated if the argument filter is null. It just takes each entry of the list (as s) and returns true.
There are two parts to this.
First, you need to adjust the NoFilter() function to be compatible with Predicate<T>. Notice the latter is generic, but the former is not. Make NoFilter() look like this:
private bool NoFilter<T>(T item) { return true; }
I know you never use the generic type argument, but it's necessary to make this compatible with your predicate signature.
For fun, you could also define NoFilter this way:
private Predicate<T> NoFilter = x => true;
Now the second part: we can look at using the new generic method as the default argument for GetItems(). The trick here is you can only use constants. While NoFilter() will never change, from the compiler's view that's not quite the same things a a formal constant. In fact, there is only one possible constant you can use for this: null. That means your method signature must look like this:
private List<thing> GetItems(Predicate<thing> filter = null)
Then you can check for null at the beginning of your function and replace it with NoFilter:
private List<thing> GetItems(Predicate<thing> filter = null)
{
if (filter == null) filter = NoFilter;
return rawList.Where(filter).ToList();
}
And if you also do want to explicitly pass this to the method when calling it, that would look like this:
var result = GetItems(NoFilter);
That should fully answer the original question, but I don't want to stop here. Let's look deeper.
Since you need the if condition anyway now, at this point I would tend to remove the NoFilter<T>() method entirely, and just do this:
private IEnumerable<thing> GetItems(Predicate<thing> filter = null)
{
if (filter == null) return rawList;
return rawList.Where(filter);
}
Note that I also changed the return type and removed the ToList() call at the end. If you find yourself calling ToList() at the end of a function just to match a List<T> return type, it's almost always much better to change the method signature to return IEnumerable<T> instead. If you really need a list (and usually, you don't), you can always call ToList() after calling the function.
This change makes your method more useful, by giving you a more abstract type that will be more compatible with other interfaces, and it potentially sets you up for a significant performance bump, both in terms of lowered memory use and in terms of lazy evaluation.
One final addition here is, if you do pare down to just IEnumerable, we can see now this method does not really provide much value at all beyond the base rawItems field. You might look at converting to a property, like this:
public IEnumerable<T> Items {get {return rawList;}}
This still allows the consumer of your type use a predicate (or not) if they want via the existing .Where() method, while also continuing to hide the underlying raw data (you can't directly just call .Add() etc on this).

Evaluating a set of rules defined in a string

I made a system that creates a simple string with Function/Response format, example:
Check('Value'):ShowImage(#)|Check('Value'):OtherFunction(#)....and so on
Where Check is the name of a function, Value is the parameter, ShowImage is the name of a Response function, # is the entry paremeter (result of the previous function). The pipe splits another Function/Response pair that fires if the first Check('Value') function once "checked" were not satisfied (say, if the parameter was not accomplished the Check condition the function is invalid and hence the Response part in the first Function/Response pair is not executed, so system keep trying Functions awaiting to find the one that executes the right Response).
The way the application should work is to evaluate each rule (similar to a JavaScript eval function) and take appropriate action based on function results.
At first glance, it looks complicated, because first of all I need to cast the string to the right real C# function that will actually process the condition. Therefore, depending on the function result, decide where to point to execute my Response function.
Furthermore: This is just the kind example, because there are functions as * that represent something like: "any condition is true" what in almost all cases this function is the last in the chain (the default function).
That's my problem, I can't realize what is the easiest way to cope with this problem.
Maybe a chain of delegates? Lambdas? Anonymous stored into a structure...
Could you give me your measure/advise? Where to start?
Depending on the level of extensibility you want to have, I would say the most extensible way would be to use reflection to get method references, after you have parsed the input string.
You can start by splitting your problem into smaller subproblems.
Let's say you are aiming for something like this:
static void Main(string[] args)
{
string rules =
"Check(Morning):Say(Good morning)|" +
"Check(Afternoon):Say(Good afternoon)|" +
"Check(Evening):Say(Good night)";
// next, you need some **object instances** which will
// provide a context for your "test" and "action" methods.
// you don't want to use static methods if you
// went through the pain of defining such an architecture!
// let's say that a "Tester" object has a "Check" method,
// and an "Executor" object has a "Say" method:
var tester = new Tester("Afternoon");
var executor = new Executor();
// since I suck at regular expressions,
// I am using plain string methods to split
// the expression into tokens. You might want
// to add some validation
foreach (var rule in rules.Split('|'))
{
var result = Parse(rule, tester, executor);
if (result.TestPassed)
{
result.Execute();
break;
}
}
}
A "result" as it's used above would then have an interface like this:
public interface IResult
{
// returns true if a test is fulfilled
bool TestPassed { get; }
// executes the related action
void Execute();
}
And, if you want to delegate actual actions to some unknown methods, a reasonable way to implement it would be something like this:
public class Result : IResult
{
#region IResult Members
private readonly Func<bool> _testMethod;
public bool TestPassed
{
get { return _testMethod(); }
}
private readonly Action _actionMethod;
public void Execute()
{
_actionMethod();
}
#endregion
public Result(Func<bool> testMethod, Action actionMethod)
{
_testMethod = testMethod;
_actionMethod = actionMethod;
}
}
What's left is to use some reflection to get the actual methods out of your strings:
private static IResult Parse(string rule, object tester, object executor)
{
// split into test/action
var tokens = rule.Split(':');
// extract the method/parameter part for each expression
var test = GetMethodAndParams(tokens[0]);
var action = GetMethodAndParams(tokens[1]);
// use reflection to find actual methods
var testMethod = tester.GetType().GetMethod(test.Method);
var actionMethod = executor.GetType().GetMethod(action.Method);
// return delegates which will simply invoke these methods
return new Result
(
() => (bool)testMethod.Invoke(tester, new object[] { test.Param }),
() => actionMethod.Invoke(executor, new object[] { action.Param })
);
}
That is, more or less, your program's skeleton. You should be able to fill in the missing parts yourself, as an exercise. If you have problems, I can update the answer later.
A GetMethodAndParams method should split the input string into a Tuple (or your custom class) which contains the method name and its params as plain strings. Tester and Executor classes can also be implemented trivially.
It looks like you want a pattern along the lines of the .NET TryParse() methods. In that case, you would modify your check method to have an out parameter that is the value (represented in your example by #).
int result;
if(Check('Value', out result))
ShowImage(result);
else(Check('Value2', out result))
OtherFunction(result);
Finally I'm back here to post what I've done few weeks ago to solve this situation.
It was easy.
Regex class provide few options, one of those is "Explicit Catpure", all streams with the form (?) can be handled as strong typed parameters so, if the named group "IsNotEmptyorNull" then the function is present and it is promotable to casting using the form Enum.Parse("").
Snipet:
Regex rx = new Regex(#"(?<function>Check|BooleanOp)\('(?<param>[\w]+)'\){1}:(?<action>[\w]+){1}", RegexOptions.ExplicitCapture);
Match m;
Dictionary<FunctionArray, String> actions = new Dictionary<FunctionArray, String>();
if((m=rx.Match(strStream)).Success)
{
actions.Add((FunctionArray)Enum.Parse(typeof(FunctionArray), m.Groups["function"].value, true), m.Groups["param"].value);
}
Of course, there are lost the action part so I've improved the Dictionary stuff with an specialized Struct that can handle the functions and values as a source for decision taking.
Thanks to all. Ed.

Categories