@kir_cipher

Как правильно реализовывать события в С#?

Товарищи! Нужен был мне класс, который будет сигнализировать об изменении своего значения. Набросал сие вот:
public class Eventable<T>
    {
        #region Var
        public T Value { get { return _value; } private set { _value = value; RaiseValueChanged(); } }
        private T _value;
        public delegate void MethodContainer();
        public event MethodContainer ValueChanged;
        #endregion

        #region Init
        public Eventable(T Value)
        {
            this.Value = Value; 
        }
        public static implicit operator Eventable<T>(T Value)
        {
            return new Eventable<T>(Value);
        }
        #endregion

        #region Actions
        protected virtual void RaiseValueChanged()
        {
            ValueChanged?.Invoke();
        }
        #endregion
    }

Но событие почему-то всегда возвращает null и, как следствие, не отрабатывает. Что я не так сделал?
  • Вопрос задан
  • 207 просмотров
Решения вопроса 2
Я с недавнего времени использую такой короткий класс в своём проекте. А в начале было слишком много событий. Теперь гоняю через конкретные имена.
public class Intercom
    {
        #region Обработка событий по изменению содержимых.
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        #region Управление свойством.
        public string Message { get; set; } = "Null";
        public bool OnEvent { get; set; } = true;
        public void Reset() { Message = "Null"; }

        #endregion

        #region Внутренее свойство события.
        private int _Calling;
        private string _Response;
        private string _Request;
        private string _Report;

        public int Calling
        {
            get { return _Calling; }
            set { _Calling = value; if (OnEvent) NotifyPropertyChanged($"Call.{Message}"); }
        }
        public string Response
        {
            get { return _Response; }
            set { _Response = value; if (OnEvent) NotifyPropertyChanged($"Response.{Message}"); }
        }
        public string Request
        {
            get { return _Request; }
            set { _Request = value; if (OnEvent) NotifyPropertyChanged($"Request.{Message}"); }
        }
        public string Report
        {
            get { return _Report; }
            set { _Report = value; if (OnEvent) NotifyPropertyChanged($"Report.{Message}"); }
        }
        #endregion
    }


А потом к нему подписываешься с помощью += <вызываемая функция>
Ответ написан
Все работает. Например, такой код
Eventable<Int32> var = 32;
var.ValueChanged += () => Console.WriteLine(var.Value);

var.Value = 34;
var.Value = 42;

Выведет 34 и 42. Единственное, сеттер значения сделал публичным, чтобы мог снаружи изменить.

Проблема возможно в том, что вы пытались сделать что-нибудь вроде var = 42, но это ведь не Value изменит, а просто новый объект создаст.

Оффтоп: MethodContainer лучше заменить на Action. А лучше на Action< T >.
Оффтоп2: А еще есть INotifyPropertyChanged, хотя, как по мне, он не очень удобен, т.к. использует строковые названия свойств, а не строго типизирован.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы