0

Imagine I want to add a response header to an HTTP request in a web app. I can do this in two ways:

var httpContext = GetHttpContext();

// No state object - OnStarting(Func<Task> callback)
httpContext.Response.OnStarting(state =>
{
    httpContext.Response.Headers.Add("My-Header", "value");
});

// Use state object - OnStarting(Func<object, Task> callback, object state);
httpContext.Response.OnStarting(state =>
{
    var headers = (IHeaderDictionary)state;

    headers.Add("My-Header", "value");
}, httpContext.Response.Headers);

Should one of these methods be preferred over the other? If so, why?

James
  • 1,028
  • 9
  • 20

1 Answers1

1

This is a difference in lamba capture. Details on their implementation.

In first scenario, an anonymous class is created by compiler, whose' instance is created to capture the value of httpContext.

In second scenario, the lambda is converted into plain static method, so no instance is created. This means simpler generated code and less garbage collector impact.

The preference is really about performance and GC optimization.

How the OP code will be translated by compiler:

Without state and with capture:

class _anonymousClass
{
    private HttpContext httpContext;
    public _anonymousClass(HttpContext httpContext)
    {
        this.httpContext = httpContext;
    }

    public void Callback()
    {
        this.httpContext.Response.Headers.Add("My-Header", "value");
    }
}

var httpContext = GetHttpContext();

// No state object - OnStarting(Func<Task> callback)
httpContext.Response.OnStarting(new _anonymousClass(httpContext).Callback);

With state and without capture:

private void _anonymousCallback(object state)
{
    var headers = (IHeaderDictionary)state;

    headers.Add("My-Header", "value");
}

// Use state object - OnStarting(Func<object, Task> callback, object state);
httpContext.Response.OnStarting(_anonymousCallback, httpContext.Response.Headers);
Euphoric
  • 12,645
  • 1
  • 30
  • 44
  • It sounds like there is little reason to use the first option - code is a little easier to read but that's it. Would you agree? – James Jan 21 '20 at 10:56
  • @James Both have their strong points. The simplicity of using lambda capture is valuable when performance is not a concern. – Euphoric Jan 21 '20 at 11:00