C#中的延迟执行

Lar*_*nal 12 c# deferred-execution

我怎样才能在C#中实现自己的延迟执行机制?

所以我举例说:

string x = DoFoo();
Run Code Online (Sandbox Code Playgroud)

是否有可能执行一些魔法,以便在我"使用"x之前DoFoo不会执行?

dtb*_*dtb 18

你可以使用lambdas/delegates:

Func<string> doit = () => DoFoo();
//  - or -
Func<string> doit = DoFoo;
Run Code Online (Sandbox Code Playgroud)

稍后您可以doit像方法一样调用:

string x = doit();
Run Code Online (Sandbox Code Playgroud)

我认为你能得到的最接近的是这样的:

Lazy<string> x = DoFoo;

string y = x; // "use" x
Run Code Online (Sandbox Code Playgroud)

定义Lazy<T>与此类似(未经测试):

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,似乎编译器的类型推理算法无法自动推断类型,Func<T>因此无法将其与隐式转换运算符相匹配.我们需要显式声明委托的类型,这使得赋值语句更加冗长:

// 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);
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,该框架的下一个版本将拥有一个漂亮的线程安全的懒惰助手类.在此之前,您可以在此处获取它的源代码:http://www.bluebytesoftware.com/blog/2007/06/09/ALazyInitializationPrimitiveForNET.aspx (2认同)

Jar*_*Par 6

一种选择是使用Lazy<T>该类,以前来自并行扩展库,现在是.Net Framework 4.0的一部分.

它允许您以线程感知的方式延迟过程数据.


小智 5

虽然它有点脏,但你总是可以使用yield关键字:

public IEnumerable<int> DoFoo() {
   Console.WriteLine("doing foo");
   yield return 10;
}

[Test]
public void TestMethod()
{
    var x = DoFoo();
    Console.WriteLine("foo aquired?");
    Console.WriteLine(x.First());
}
Run Code Online (Sandbox Code Playgroud)