Как сделать это свойство таким, чтобы оно создавалось только при первом доступе к нему? - PullRequest
0 голосов
/ 13 января 2012

У меня есть следующий код:

/// <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, что мне и нужно сделать в свойстве Shared, когда пользователь получает (после повторного присоединения).

Я не вижу, как яможет ли это без дублирования моей логики .set общих свойств в .get.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 13 января 2012

Вы можете использовать этот шаблон как для статических, так и для экземпляров:

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

Это называется ленивым воплощением.


EDIT:

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;
    }
}
0 голосов
/ 13 января 2012

Сохраните частную переменную уровня класса SharedBrowser, затем проверьте, имеет ли она значение null в вашем блоке get.Затем, чтобы завершить вашу дополнительную логику инициализации, преобразовать ее в другой метод и вызвать ее из get и set.

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.
}
0 голосов
/ 13 января 2012

Хорошая вещь в статическом конструкторе - вы знаете, что он будет вызываться только один раз для каждого приложения. У вас нет такой гарантии позже. Так что добавьте статический конструктор и поместите в него экземпляр в Lazy , а затем ссылайтесь на .Value Lazy в вашем .get

...