Misuse of Delegates???

In the evolution of the ideas presented in Java, C# has provided the idea of method delegation and delegates, which I'm sure you are well aware of. In C# 3.0 with the introduction of the LINQ, Lambdas were born. With Lambdas, we are able to provide an easy and elegant way to declare delegates. With great power, however, comes great responsibility. Is there a way to overuse Lambdas and Delegates? Here is a sample of code I've written:

/// <summary>
/// If GZIP or DEFLATE compression is accepted
/// by the user's browser, we will go ahead
/// and compress the file upon the controller action
/// </summary>
/// <param name="controller">Controller to invoke Compression</param>
public static void Compress(this Controller controller)
{
    string gzip = "gzip";
    string deflate = "deflate";
 
    //DELEGATES
    Func<string, bool> isAccepted = (encoding) => controller.Request.Headers["Accept-encoding"] != null && controller.Request.Headers["Accept-encoding"].Contains(encoding);
    Action<string> setEncoding = (encoding) => controller.Response.AppendHeader("Content-encoding", encoding);
 
    if (isAccepted.Invoke(gzip))
    {
        controller.Response.Filter = new GZipStream(controller.Response.Filter, CompressionMode.Compress);
        setEncoding.Invoke(gzip);
    }
    else if (isAccepted.Invoke(deflate))
    {
        controller.Response.Filter = new DeflateStream(controller.Response.Filter, CompressionMode.Compress);
        setEncoding.Invoke(deflate);
    }
}

 

As you can see from the code, I use the .NET built-in delegates of Action and Func to do the setting of the encoding and the determination of the encoding, respectively.

 

So here is my question: Is this a misuse of delegates? Should I be putting the code into a separate private method? What are your thoughts?

7 Comments

  • The purpose of a delegate is, as its name indicates, to delegate some logic in another one, basically the substitute the old void* for C and allow us to pass methods as parameters to other methods.

    It's not that is a misuse of delegates, it's just that it make no sense to us them in that way. They are meant to be used as parameters!!

    So in your example why don't you just do


    bool isAccepted = controller.Request.Headers["Accept-encoding"] != null && controller.Request.Headers["Accept-encoding"].Contains(encoding);

    if (isAccepted)
    ...


    What is to gain by the use of a delegate?

  • @Jorge

    The code you provided would require that code to be written twice, which is what we want to avoid. Look at the code closer, you'll see that isAccepted.Invoke is indeed invoked twise (at most) and so is setEncoding.Invoke.

  • @JV

    Just because you can use something, doesn't mean you always should :)

  • Zowens,

    the purpose of a delegate is not to avoid code repetition, that function correspond to methods. If you review your code and think of a delegate as a pointer to a function the equivalent of what you have written would be:

    bool isAccepted(string encoding)
    {
    return controller.Request.Headers["Accept-encoding"] != null && controller.Request.Headers["Accept-encoding"].Contains(encoding);
    }

    {
    ...
    void* func = isAccepted;
    ...
    if (func(gzip))
    ...

    Keep in mind, delegates are just function pointers and they are ment to allow us to pass the function as a parameter because doing

    MyFunction(param1, param2, IsAccepted)

    would be difficult to evaluate by the compiler since IsAccepted is located in the code section (and we at leas the reference in the stack to be able to correctly interpret it)

    So using a delegate instead of a proper function just doesn't make sense. In addition, if the segment of code is just that short I won't even refactor it into a method (compiler would inline it anyway) because it's clearer if we can actually see the code, even if its repeated twice.

  • Inapropriate use.

    "Look at the code closer".
    Exactly the problem, the code has made a short term trade off of how much you need to write at the cost of how easy the code is to understand.


  • @zowens. True, but that's also the reason I said: "I wouldn't call it misuse either.". It's just another solution, which I personally wouldn't prefer in this scenario.

    If you mean the part in which I mentioned we will see this kind of code very often soon: I meant that because lots of developers tend to misuse/abuse/etc.. new features for every kind of functionality they can think of. Without, unlike you, asking themselves, should I actually be using this here?

  • @JV - You bring up a good point, the point I am trying to make, which is what should the convention be? I could use a normal method. Or I could use it inline. But, lets be honest Jorge, code repetition is a poor coding practice. Using delegates solves this problem... I didn't say it was the point of a delegate at all.

    Perhaps this solution... add an extension method to Request and response? This way, the code is easy to read by the Compress method and we can reuse the logic in other places. Oh boy do I like to over-use extension methods :)

Comments have been disabled for this content.