开发者

Func Delegate vs Function

开发者 https://www.devze.com 2023-01-05 03:25 出处:网络
Can someone tell me the advantages of using a delegate as opposed to calling the function itself as shown below (or in other word开发者_JAVA技巧s why choose Option A over Option B)?I was looking at so

Can someone tell me the advantages of using a delegate as opposed to calling the function itself as shown below (or in other word开发者_JAVA技巧s 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消