Какая-то круговая повторяющаяся обработка событий здесь? Но что и как? - PullRequest
0 голосов
/ 25 апреля 2018

Как можно избежать этого предупреждающего сообщения в VS2017 (или: что может происходить):

'ObsCol<T>.ObsCol()' contains a call chain that results in a call to a virtual method
defined by the class.
Review the following call stack for unintended consequences: 

ObsCol<T>..ctor()
ObservableCollection<T>.add_CollectionChanged(NotifyCollectionChangedEventHandler): Void 

это код:

[Serializable]
public class ObsCol<T> : ObservableCollection<T> 
{
   public ObsCol()
   {
      this.CollectionChanged += new NotifyCollectionChangedEventHandler(ObsCol_CollectionChanged);
   }       

   private void ObsCol_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
   {
       if (e.Action == NotifyCollectionChangedAction.Add)
       MainViewModel.IsDirty = e.NewItems != null || e.OldItems != null;

   }
}

Цель всего этогознать во ViewModel, соответствуют ли выходные данные расчета входным данным.При входе в конструктор CollectionChanged пуст, поэтому мой обработчик - единственная вещь в списке.

Изменение CollectionChanged не меняет коллекцию, не так ли?

Кажется, все работает нормально...

1 Ответ

0 голосов
/ 06 июня 2018

Проблема: некоторый подкласс может переопределить событие, что приведет к неожиданному поведению при построении

public class Boom<T> : ObsCol<T>
{
    public override event NotifyCollectionChangedEventHandler CollectionChanged
    {
        add { throw new NotImplementedException(); }
        remove { }
    }
}

Решения:

Использовать OnCollectionChanged переопределить

public class Solution1<T> : ObservableCollection<T>
{
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
            DoSomething();

        base.OnCollectionChanged(e);
    }

    ...
}

Печать класса

public sealed class Solution2<T> : ObservableCollection<T>
{
    public Solution2()
    {
        this.CollectionChanged += new NotifyCollectionChangedEventHandler(ObsCol_CollectionChanged);
    }

    ...
}

Печать события

public class Solution3<T> : ObservableCollection<T>
{
    public sealed override event NotifyCollectionChangedEventHandler CollectionChanged
    {
        add { base.CollectionChanged += value; }
        remove { base.CollectionChanged -= value; }
    }


    ...
}

То, что вы делаете, зависит от вашего варианта использования ... первое решение наиболее гибкое, поскольку вы все равно можете создавать подклассы со всеми видами переопределений.

С учетом SerializableAttribute в вашем вопросе, возможно, стоит запечатать весь класс, так как вы, вероятно, все равно не хотите сериализовать подтипы (Решение 2).

Если вы когда-либо оказались в ситуации, когда метод OnEvent / RaiseEvent по какой-либо причине недоступен, Решение 3 позволяет запечатать только минимальное подмножество функций, которое используется в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...