2014-01-06 1 views
1

Я задаюсь вопросом, как «ленивый» экземпляр объекта из обработчика событийЛенивый инициализации в обработчике события

Если у меня есть приложение WinForms и две кнопки, например:

public partial class Form1 : Form 
{ 
    //MyClass obj = new MyClass(); 

    MyClass obj; 

    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     obj = new MyClass(); 
     obj.StartWork(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     obj.StopWork(); 
    } 
} 

Поскольку мы выиграли «Мне нужно получить доступ к членам MyClass до того, как пользователь нажмет кнопку 1, имеет смысл только создать экземпляр класса в этом обработчике событий. Тем не менее, нажатие на вторую кнопку приведет к исключению нулевой ссылки, потому что переменная obj в этой области ничего не ссылается.

+0

не следует отключать кнопку2 до тех пор, пока не будет нажата кнопка 1, не можете ли вы сделать это только с помощью одной кнопки? – RoughPlace

+0

вы можете обернуть obj в proprety, создать экземпляр в методе get. –

ответ

4

Вы можете использовать Lazy<T>.

public partial class Form1 : Form 
{ 
    Lazy<MyClass> obj = new Lazy<MyClass>(); 

    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     obj.Value.StartWork(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     obj.Value.StopWork(); 
    } 
} 

Доступ к его свойству Value будет форсировать создание объекта.

Вы также можете предоставить настраиваемую функцию инициализации для конструктора Lazy.

+0

Спасибо. Это работает. Итак, с классом Lazy создание происходит только тогда, когда мы используем свойство value в коде, а не раньше? – Mefhisto1

+0

Несомненно, это не собирается строить, как есть. 'MyClass' будет инициализирован при построении. Органы обработчика событий не скомпилируются. – Gusdor

+0

@user: Верно. (Но я забыл изменить тип на 'Lazy ' в моем примере, теперь фиксированном). –

1

Это должно остановить исключение:

private void button2_Click(object sender, EventArgs e) 
{ 
    // You need to make sure that obj is not null when this button is clicked. 
    // One way is to disable this button until button1 is pressed. 
    // Or you can add this if statement. 
    if(obj != null) 
    { 
     obj.StopWork(); 
    } 
} 

Но ваше заявление

потому OBJ переменная в этой области видимости ничего не ссылается

неправильно. obj могут быть доступны всеми способами в вашем классе Form1. Поэтому, когда вы сначала нажимаете на button1, вы создаете экземпляр переменной obj, которая может использоваться в любом месте вашего класса. Но вам нужно добавить if(obj != null), если пользователь нажмет на button2.

+0

Это не глобальное - это поле. –

+1

Это глобально в вашем классе Form1. Но вы, вероятно, получили исключение NullReferenceException, нажав кнопку2 без первого нажатия на кнопку1. –

+1

'member', no globals in C# – Gusdor