代码之家  ›  专栏  ›  技术社区  ›  Larsenal

C语言中的延迟执行#

  •  12
  • Larsenal  · 技术社区  · 15 年前

    如何在C#中实现自己的延迟执行机制?

    例如,我有:

    string x = DoFoo();
    

    是否可以执行一些魔术,使DoFoo在我“使用”x之前不会执行?

    6 回复  |  直到 15 年前
        1
  •  19
  •   LukeH    15 年前

    您可以使用lambda/delegate:

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

    doit 就像一种方法:

    string x = doit();
    

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

    Lazy<string> x = DoFoo;
    
    string y = x; // "use" x
    

    定义为 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;
        }
    }
    

    不幸的是,编译器的类型推断算法似乎无法自动推断 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);
    
        2
  •  6
  •   JaredPar    15 年前
        3
  •  4
  •   Jack Murphy    15 年前

    虽然有点脏,但您可以始终使用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());
    }
    
        4
  •  1
  •   spender    15 年前

    x ,将获取字符串的委托传递给您

    Func<String> fooFunc=()=>DoFoo();
    
        5
  •  0
  •   Noon Silk    15 年前

    --编辑

    我是说,你说的“使用”是什么意思

    例如,如果希望在调用“.ToString()”时调用它,则始终可以继承该类并在该类中实现函数(但这将非常不直观)。

        6
  •  0
  •   Remus Rusanu    15 年前

    IQueryable<string> 你需要一个 string