Как я могу сделать использование пользовательских событий в моих классах необязательным? - PullRequest
2 голосов
/ 09 февраля 2010

Когда я комментирую строку fm.OnLoaded ниже, я получаю сообщение об ошибке, что OnLoaded имеет значение null.

Как я могу сделать необязательным для вызывающего абонента моего класса использование события или нет, как для классов / событий .NET?

using System;
using System.Windows;

namespace TestEventLoaded8282
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            FileManager fm = new FileManager();
            //fm.OnLoaded += new FileManager.LoadedHandler(fm_OnLoaded);
            fm.Load();
        }

        void fm_OnLoaded(object obj, FileManagerArgs args)
        {
            Console.WriteLine("the file manager is loaded: " + args.Message); 
        }
    }

    public class FileManager
    {
        public string Name { get; set; }

        public delegate void LoadedHandler(object obj, FileManagerArgs args);
        public event LoadedHandler OnLoaded;

        public FileManager()
        {}

        public void Load()
        {
            Name = "this is the test file manager";
            OnLoaded(this, new FileManagerArgs("no errors"));
        }
    }

    public class FileManagerArgs : EventArgs
    {
        public string Message { get; set; }

        public FileManagerArgs(string message)
        {
            Message = message;
        }
    }
}

Ответы [ 3 ]

5 голосов
/ 09 февраля 2010
if (OnLoaded != null) {
    OnLoaded(this, new FileManagerArgs("no errors"));
}
3 голосов
/ 09 февраля 2010

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

LoadedHandler handler = OnLoaded;

if (handler != null)
{
    handler(this, new FileManagerArgs("no errors"));
}

Вам нужно будет делать это каждый раз, когда вы вызываете обработчик события. Локальная переменная handler, указанная выше, предназначена для отслеживания случая, когда вы можете проверить, что обработчик не равен NULL, но что-то удаляет обработчик перед его вызовом. Создание локальной переменной захватывает обработчик, чтобы предотвратить это.

Альтернативный подход состоит в том, чтобы определить обработчик событий как:

public event LoadedHandler OnLoaded = delegate{};

Здесь объявляется пустой обработчик событий по умолчанию, что делает ненужной проверку нуля (хотя при таком подходе наблюдается небольшая потеря производительности).

3 голосов
/ 09 февраля 2010

Проверьте на нулевое значение перед вызовом делегата. Ниже приведен общий шаблон:

public event EventHandler<FileManagerEventArgs> Loaded;

public void Load()
{
    ...
    OnLoaded(new FileManagerEventArgs("no errors"));
}

protected virtual void OnLoaded(FileManagerEventArgs e)
{
    EventHandler<FileManagerEventArgs> handler = this.Loaded;
    if (handler != null)
    {
        handler(this, e);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...