我有一个类DataAdapter,该类由我的站点实例化为单例对象。该类具有一个Person属性,我想成为一个懒惰的单例,实现此目的的代码:private readonly object _personLock = new object();private volatile IPersonManager _person;public IPersonManager Person{ get { if (_person == null) { lock (_personLock) { if (_person == null) { _person = new PersonManager(_adUserName, _adPassword, client); } } } return _person; }}(PersonManager构造函数的三个参数是当前对象的属性/字段。)该代码可以完美运行(这是一个double-lock check模式)。但是,这是很多代码,我想利用.Net 4.0中的新Lazy<> type使其更简单。所以我将代码更改为: private static readonly Lazy<IPersonManager> _person = new Lazy<IPersonManager>(() => new PersonManager(_adUserName, _adPassword, client)); public static IPersonManager Person { get { return _person.Value; } }但这是行不通的,因为这三个参数不是静态的(它们是当前方法上的实例对象)。 write ups I've found均未解决此问题。我需要某种方式将这些值传递到该lambda表达式中? Lazy 类看起来像是一个空的签名。 (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 好吧,如果Lazy使用Instance属性与单例实例一起为自己提供属性呢?这些字段仍然可以是私有的,因为我们是在类(聪明的)内部使用它们的,并且在执行过程中首次引用Singleton.Instance之前,整个过程仍然很懒。但是,在代码尝试获取Person属性之前,私有字段必须具有适当的值。如果在Singleton实例化时急切地加载它们,那很好。从C# In Depth借用,这是一个准懒惰的Singleton,具有完全懒惰的Person成员,该成员使用引用Singleton的lambda初始化。public sealed class Singleton{ private static readonly Singleton instance = new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } private Singleton() { //I HIGHLY recommend you initialize _adusername, //_adpassword and client here. } public static Singleton Instance { get { return instance; } } private static readonly Lazy<IPersonManager> _person = new Lazy<IPersonManager>(() => new PersonManager(Instance._adUserName, Instance._adPassword, Instance.client)); public static IPersonManager Person { get { return _person.Value; } } private object _adUserName; private object _adPassword; private object client;}public class PersonManager:IPersonManager {}public interface IPersonManager{}编辑:如果您有IoC,请使用IoC。您目前正在尝试混合模式;您正在使用IoC使用运行时规则将实例类“提升”为单例,然后尝试根据该伪单例的实例作用域数据字段实例化编译器强制的惰性静态属性。这根本行不通一旦您进入IoC,应该注册并注入每个依赖项。向Ninject注册PersonManager作为IPersonManager的实现,然后为您的主单例DataAdapter创建一个构造函数,可以为其提供一个生成IPersonManager的Func。通常,您可以为此定义一个自定义函数,这种情况下,您将利用IoC从容器中保存的单个DataAdapter实例中提供所需的实例数据。警告:这些数据字段现在必须是公共可读的,以避免某些严重的丑陋反映;您可以将字段定义为只读字段或只读属性,以防止人们篡改它们,但您的消费者将能够看到它们。编辑2:这就是我的想法://in your Ninject bindings:kernel.Bind<DataAdapter>().ToSelf().InSingletonScope();kernel.Bind<PersonManager>().ToSelf().InSingletonScope();//to bind the interfacekernel.Bind<IPersonManager>() .ToMethod(c =>{ var adapter = kernel.Get<DataAdapter>(); //this is why these fields would have to be public var arg1 = new ConstructorArgument("adUserName", adapter._adUserName) var arg2 = new ConstructorArgument("adPassword", adapter._adPassword) var arg3 = new ConstructorArgument("client", adapter.client) //the names of the arguments must match PersonManager's constructor c.Kernel.Get<PersonManager>(arg1, arg2, arg3); });//now in your DataAdapter, specify a constructor like this, and Ninject will provide:public DataAdapter(Func<IPersonManager> personFunc){ //_person should obviously not be instantiated where it's defined in this case _person = new Lazy<IPersonManager>(personFunc);}关于c# - .Net懒惰初始化Singleton属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9297500/ (adsbygoogle = window.adsbygoogle || []).push({});
10-09 06:36