我正在读一些.NET 4+代码,它在Lazy的构造函数中使用了一个lambda,就像这个new Lazy<Foo>(() => new Foo())
。当没有参数传递给Foo
的构造函数时,它与new Lazy<Foo>()
有什么不同?从新的懒惰<Foo>()到新的懒惰<Foo>(()=> new Foo())有什么不同?
回答
如果你看看摘要问题的两个构造...
// Summary:
// Provides support for lazy initialization.
//
// Type parameters:
// T:
// Specifies the type of object that is being lazily initialized.
public class Lazy<T> {
// Summary:
// Initializes a new instance of the System.Lazy<T> class. When lazy initialization
// occurs, the default constructor of the target type is used.
public Lazy();
//
// Summary:
// Initializes a new instance of the System.Lazy<T> class. When lazy initialization
// occurs, the specified initialization function is used.
//
// Parameters:
// valueFactory:
// The delegate that is invoked to produce the lazily initialized value when
// it is needed.
//
// Exceptions:
// System.ArgumentNullException:
// valueFactory is null.
public Lazy(Func<T> valueFactory);
}
这就是说,主要的区别是,你能做些什么类型的第二个构造
如。 ...
new Lazy<Foo>(() => new Foo(){ SomeProperty = someValue});
new Lazy<Foo>(() => new Foo(someValue));
......这与默认的构造函数不同。
此外,如果该类型没有默认构造函数而没有参数,则new Lazy<T>()
可能会失败。
从我的理解你会使用lambda表达式的形式,当你想传递参数在初始化中使用。我不认为没有参数的lambda有用例。
待NIT挑剔,反射创建对象的实例比执行更慢一个lambda来构造实例。当然,根据你的用例,它可能根本不重要,但某个地方的某个人可能会有一个用例。 –
我同意但是(有点)讽刺的是,不是5分钟前我刚刚看到这个链接的另一个问题,你的评论让我想起了它。 [Performance Rant](https://ericlippert.com/2012/12/17/performance-rant/) –
new Lazy<Foo>()
使用反射来创建一个Foo
的实例,使用类似下面的代码Activator.CreateInstance(typeof(T))
来调用默认构造函数。这意味着Foo
必须具有默认构造函数。
另一方面,如果需要,Lazy<Foo>(Func<T>)
为您构建通过Lazy类型创建的实例提供了更大的灵活性。
当类型可以使用默认构造函数实例化时,默认的Lazy构造函数很有用。这意味着new Lazy<Foo>(() => new Foo())
,其中Foo
不采用构造参数,在大多数情况下可简化为new Lazy<Foo>()
。
例外是当类型的构造函数是私有的 - 因为如前所述默认的Lazy<T>
构造函数使用Activator.CreateInstance(typeof(T))
,如果构造函数是私有的,即使它没有参数,这也不起作用。例如,如下一个可能实现使用Lazy<T>
单身:
public class Foo
{
// Notice that the Lazy(Func<T>) constructor is used here
// because Foo's constructor is private
private static readonly Lazy<Foo> _instance = new Lazy<Foo>(() => new Foo());
public static Foo Current => _instance.Value;
private Foo()
{
// Don't allow calling code to new
}
}
- 1. 为什么懒惰<T>不懒惰?
- 2. 封装懒惰<T>
- 3. 不能隐含地将懒惰<Class>转换为懒惰<Interface>
- 4. 缓存属性vs懒惰<T>
- 5. 手动设置懒惰值<T>
- 6. C#懒惰<T>&Race-to-initialize?
- 7. 懒惰的缺点<T>?
- 8. 懒惰评价不那么懒惰?
- 9. 懒惰<T>与LazyThreadSafeMode.PublicationOnly和IDisposable
- 10. 懒惰<T> - 总是创建一个新的对象?
- 11. 如何调试懒惰<T>?
- 12. 懒惰<T>和LazyInit之间的区别<T>
- 13. 懒惰<T>如何解决需要new()约束?
- 14. 懒惰加载和懒惰评估有什么区别?
- 15. MEF:懒惰<T>类型的反义词是什么?
- 16. 懒惰<T>重新初始化方法?
- 17. 懒惰的val做什么?
- 18. 为什么懒惰<T>受限于静态上下文?
- 19. F#懒惰评估与非懒惰
- 20. 是什么让一个符号变成懒惰或非懒惰?
- 21. 什么是“懒惰缓存”?
- 22. Java正则表达式懒惰操作符不那么懒惰?
- 23. Resharper Refactor字段的类型T到懒惰<T>
- 24. CompositDisposable不够懒惰?
- 25. hGetContents太懒惰
- 26. 关于懒惰
- 27. SimpleInjector RegisterAll懒惰地
- 28. Swift中的懒惰
- 29. preg_match懒惰?
- 30. 懒惰SlidingDrawer
没关系,这是一个愚蠢的问题的答案就在问题本身 – Jack