如何创建此属性,以便仅在我第一次访问它时创建它?

时间:2012-01-12 21:13:22

标签: c# lazy-evaluation

我有以下代码:

/// <summary>
/// BrowserFactory responsible for deciding if you should receive a shared or isolated browser instance.
/// </summary>
public static class BrowserFactory
{
    /// <summary>
    /// Shared Browser Instance
    /// </summary>
    private static SharedBrowser _sharedBrowser;

    /// <summary>
    /// The window handle of the shared browser instance.
    /// </summary>
    private static string _sharedHwnd;

    /// <summary>
    /// The last thread id to access the shared browser.
    /// </summary>
    private static int _sharedThreadId;

    static BrowserFactory()
    {
        Shared= new SharedBrowser();
    }       

    private static SharedBrowser Shared
    {
        get
        {
            var currentThreadId = GetCurrentThreadId();
            if (currentThreadId != _sharedThreadId)
            {
                _sharedBrowser = IE.AttachTo<SharedBrowser>(Find.By("hwnd", _sharedHwnd));
                _sharedThreadId = currentThreadId;
            }
            return _sharedBrowser;
        }
        set
        {
            _sharedBrowser = value;
            _sharedHwnd = _sharedBrowser.hWnd.ToString();
            _sharedThreadId = GetCurrentThreadId();
        }
    }

    public static Browser GetBrowser()
    {
        return BrowserSettings.UseSharedBrowser ? Shared : new Browser();
    }
}

我怎样才能这样做,所以我只在首次访问属性时而不是在构造函数中实例化SharedBrowser对象?

起初我想在Shared属性中做到这一点,但是从属性get调用一个集合似乎很奇怪。

我还考虑过将_sharedBrowser包含在.NET 4.0 Lazy对象中,但后来我不确定如何直接实例化Lazy中包含的东西,这是我在共享属性中需要做的事情获得(重新附加后)。

我没有看到如何在不重复.get中的共享属性.set逻辑的情况下实现这一点。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您可以将此模式用于静态成员以及例如成员:

private SomeType _myProperty;
public SomeType MyProperty
{
    get
    {
        if (_myProperty == null) {
            _myProperty = new SomeType();
        }
        return _myProperty;
    }
}

这称为惰性实例化。


编辑:

private static SharedBrowser _shared;
public static SharedBrowser Shared {
    get
    {
        var currentThreadId = GetCurrentThreadId();          
        if _shared == null) {
            _shared = new SharedBrowser();
            _sharedHwnd = _sharedBrowser.hWnd.ToString();
            _sharedThreadId = currentThreadId;         
        }
        if (currentThreadId != _sharedThreadId) {          
            _sharedBrowser = IE.AttachTo<SharedBrowser>(Find.By("hwnd", _sharedHwnd));          
            _sharedThreadId = currentThreadId;          
        }          
        return _shared;
    }
}

答案 1 :(得分:0)

关于静态构造函数的好处是你知道每个应用程序只调用一次。你以后没有这种保证。所以添加一个静态构造函数并将实例化包装在Lazy&lt; T>在其中,然后在.get

中引用Lazy的.Value

答案 2 :(得分:0)

存储私有类级别的SharedBrowser变量,然后检查get块中的null。然后完成额外的初始化逻辑,将其重构为另一个方法,并从getset调用它。

private static SharedBrowser _shared = null;

private static SharedBrowser Shared
{
    get
    {
        if(_shared == null)
        {
            _shared = new SharedBrowser();
            InitSharedBrowser();
        }

        // the rest of your code here.
    }
    set
    {
            _shared = value;
            InitSharedBrowser();
    }
}

private static void InitSharedBrowser()
{
    // your SharedBrowser Initialization logic goes here.
}