Lazy<T> 为什么会得到 Func<T>
Lazy<T> why does it get Func<T>
谁能简单解释一下,为什么C#中的Lazy需要获取Func?
public Lazy (Func<T> valueFactory);
我知道有时候你需要一个函数来做一些花哨的事情 init().
然而,很多时候我发现自己在写一个单例,或者一些简单的东西,只需要创建一个 class 的新实例。
正如乔恩的双向飞碟书中所示。
http://csharpindepth.com/Articles/General/Singleton.aspx
我觉得这个语法很烦人。
谢谢!
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
您需要一个函数,因为如果您可以这样做:
var Lazy<Foo> = new Lazy<Foo>(new Foo());
您已经实例化了您不想要的 Foo
,否则您不必使用 Lazy<T>
开始。
Func<T>
包含 Foo
的初始化器,但仅在您访问 Lazy<T>
的 Value
.
时初始化它
如果没有初始化函数,您将无法使 Lazy
工作。这就是它如何确保创建对象的逻辑存在,但尚未调用。
考虑一下:
new Lazy<Singleton>(new Singleton());
这已经实例化了一个新的 Singleton
。懒惰的人再也没有用了。该函数允许Lazy<T>
在未来的任何时候构造对象。
Func<T>
的另一个优点是它不需要是它实例化的新对象。它可以是任何其他东西。它可以是多行语句、获取其他内容等。
我可以争论的一个优化是 new Lazy<T>()
将在 T
上使用 new()
,这样您就不需要调用构造函数。然而,这对于当前语法是不可能的,但它适用于静态工厂方法。
类似这样的事情(是的,它基本上是做你现在做的,但随后隐藏在核心中):
public static class LazyDefault
{
public static Lazy<TNew> New<TNew>() where TNew : new()
{
return new Lazy<TNew>(() => new TNew());
}
}
或者如 CodeCaster 所建议的派生 class:
public class SuperLazy<T> : Lazy<T>
where T : new()
{
public SuperLazy()
: base(() => new T())
{
}
}
你给 Lazy<T>
构造函数的东西被称为 thunk (Wikipedia):
In computer programming, a thunk is a subroutine used to inject an
additional calculation into another subroutine. Thunks are primarily
used to delay a calculation until its result is needed, or to insert
operations at the beginning or end of the other subroutine. They have
a variety of other applications in compiler code generation and
modular programming.
也就是说,惰性求值的核心是将整个要求值的东西延迟到真正需要的时候。
如果您觉得必须明确提供 Func<T>
很烦人,您可以通过以下方式简化它:
public static class Lazy
{
public static Lazy<T> Of<T>()
where T : class, new() => new Lazy<T>(() => new T())
}
var lazyFoo = Lazy.Of<Foo>()
Lazy
需要一个 Func
来实际初始化内部值。使用 Lazy 的全部目的是仅在需要时才初始化一个值。所以应该有一种 Lazy 方法可以在需要时实际初始化值,这就是 Func
的用武之地。除了传递初始化函数之外,我没有看到任何其他方法来实现类似 Lazy
的东西。
谁能简单解释一下,为什么C#中的Lazy需要获取Func?
public Lazy (Func<T> valueFactory);
我知道有时候你需要一个函数来做一些花哨的事情 init().
然而,很多时候我发现自己在写一个单例,或者一些简单的东西,只需要创建一个 class 的新实例。
正如乔恩的双向飞碟书中所示。
http://csharpindepth.com/Articles/General/Singleton.aspx
我觉得这个语法很烦人。
谢谢!
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
您需要一个函数,因为如果您可以这样做:
var Lazy<Foo> = new Lazy<Foo>(new Foo());
您已经实例化了您不想要的 Foo
,否则您不必使用 Lazy<T>
开始。
Func<T>
包含 Foo
的初始化器,但仅在您访问 Lazy<T>
的 Value
.
如果没有初始化函数,您将无法使 Lazy
工作。这就是它如何确保创建对象的逻辑存在,但尚未调用。
考虑一下:
new Lazy<Singleton>(new Singleton());
这已经实例化了一个新的 Singleton
。懒惰的人再也没有用了。该函数允许Lazy<T>
在未来的任何时候构造对象。
Func<T>
的另一个优点是它不需要是它实例化的新对象。它可以是任何其他东西。它可以是多行语句、获取其他内容等。
我可以争论的一个优化是 new Lazy<T>()
将在 T
上使用 new()
,这样您就不需要调用构造函数。然而,这对于当前语法是不可能的,但它适用于静态工厂方法。
类似这样的事情(是的,它基本上是做你现在做的,但随后隐藏在核心中):
public static class LazyDefault
{
public static Lazy<TNew> New<TNew>() where TNew : new()
{
return new Lazy<TNew>(() => new TNew());
}
}
或者如 CodeCaster 所建议的派生 class:
public class SuperLazy<T> : Lazy<T>
where T : new()
{
public SuperLazy()
: base(() => new T())
{
}
}
你给 Lazy<T>
构造函数的东西被称为 thunk (Wikipedia):
In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine. They have a variety of other applications in compiler code generation and modular programming.
也就是说,惰性求值的核心是将整个要求值的东西延迟到真正需要的时候。
如果您觉得必须明确提供 Func<T>
很烦人,您可以通过以下方式简化它:
public static class Lazy
{
public static Lazy<T> Of<T>()
where T : class, new() => new Lazy<T>(() => new T())
}
var lazyFoo = Lazy.Of<Foo>()
Lazy
需要一个 Func
来实际初始化内部值。使用 Lazy 的全部目的是仅在需要时才初始化一个值。所以应该有一种 Lazy 方法可以在需要时实际初始化值,这就是 Func
的用武之地。除了传递初始化函数之外,我没有看到任何其他方法来实现类似 Lazy
的东西。