[英]Deferred execution in C#
我怎样才能在C#中实现自己的延迟执行机制?
所以我举例说:
string x = DoFoo();
是否有可能执行一些魔法,以便在我“使用”x之前DoFoo不会执行?
你可以使用lambdas / delegates:
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);
一种选择是使用Lazy<T>
类,以前来自并行扩展库,现在是.Net Framework 4.0的一部分。
它允许您以线程感知的方式延迟过程数据。
虽然它有点脏,但你总是可以使用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());
}
而不是传递字符串x ,传递一个委托给你一个字符串
Func<String> fooFunc=()=>DoFoo();
为什么不直接调用'DoFoo()'直到你想要?
- 编辑
我的意思是,你是什么意思“使用”
例如,如果你希望在调用'.ToString()'时调用它,你总是可以继承该类并在那里实现你的函数(但这将是非常不直观的恕我直言)。
你几乎都在描述LINQ的实际应用。 linq查询描述了如何获取数据,但只有在迭代查询时才会检索数据(调用DoFunc)。 考虑是否可以将设计更改为接受需要string
IQueryable<string>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.