Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deferred execution in C#

How could I implement my own deferred execution mechanism in C#?

So for instance I have:

string x = DoFoo();

Is it possible to perform some magic so that DoFoo does not execute until I "use" x?

like image 865
Larsenal Avatar asked Sep 10 '09 01:09

Larsenal


People also ask

What is meant by deferred execution?

Deferred query executionExecution of the query is deferred until the query variable is iterated over in a foreach or For Each loop. This is known as deferred execution; that is, query execution occurs some time after the query is constructed. This means that you can execute a query as frequently as you want to.

What is deferred execution and immediate execution?

The basic difference between a Deferred execution vs Immediate execution is that Deferred execution of queries produce a sequence of values, whereas Immediate execution of queries return a singleton value and is executed immediately.

What are the benefits of a deferred execution in LINQ?

Benefits of Deferred Execution –It avoids unnecessary query execution and hence improves performance. Query construction and Query execution are decoupled, so we can create the LINQ query in several steps. A deferred execution query is reevaluated when you re-enumerate – hence we always get the latest data.

What construct does LINQ use to offer deferred execution?

Example: Use the yield return construct in an extension method to defer execution. The following example shows the order of execution when using an extension method that uses deferred execution. The example declares an array of three strings.


2 Answers

You can use lambdas/delegates:

Func<string> doit = () => DoFoo();
//  - or -
Func<string> doit = DoFoo;

Later you can invoke doit just like a method:

string x = doit();

I think the closest you can get is something like this:

Lazy<string> x = DoFoo;

string y = x; // "use" x

With a definition of Lazy<T> similar to this (untested):

public class Lazy<T>
{
    private readonly Func<T> func;
    private bool hasValue;
    private T value;

    public Lazy(Func<T> func)
    {
        this.func = func;
        this.hasValue = false;
    }

    public static implicit operator Lazy<T>(Func<T> func)
    {
        return new Lazy<T>(func);
    }

    public static implicit operator T(Lazy<T> lazy)
    {
        if (!lazy.hasValue)
        {
            lazy.value = lazy.func();
            lazy.hasValue = true;
        }
        return lazy.value;
    }
}

Unfortunately, it seems that the compiler's type inferencing algorithms can't auto-infer the type of the Func<T> and so can't match it to the implicit conversion operator. We need to explicitly declare the delegate's type, which makes the assignment statements more verbose:

// none of these will compile...
Lazy<string> x = DoFoo;
Lazy<string> y = () => DoFoo();
Lazy<string> z = delegate() { return DoFoo(); };

// these all work...
Lazy<string> a = (Func<string>)DoFoo;
Lazy<string> b = (Func<string>)(() => DoFoo());
Lazy<string> c = new Func<string>(DoFoo);
Lazy<string> d = new Func<string>(() => DoFoo());
Lazy<string> e = new Lazy<string>(DoFoo);
Lazy<string> f = new Lazy<string>(() => DoFoo);
like image 149
dtb Avatar answered Sep 20 '22 17:09

dtb


One option is to use the Lazy<T> class, formerly from the parallel extensions library now a part of the .Net Framework 4.0.

  • Reference: http://msdn.microsoft.com/en-us/library/dd642331(VS.100).aspx

It allows you to delay process data in a thread aware manner.

like image 33
JaredPar Avatar answered Sep 21 '22 17:09

JaredPar