Как привести объект, полученный мною, в ObservableCollection <T> - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь изучить отражение, поэтому я пишу метод расширения для ObservableCollection<T> (где T: IChangeTracking), который вызывает AcceptChanges () для всех элементов коллекции, но также рекурсивно для всех свойств объектов в коллекции которые реализуют IChangeTracking, если эти свойства также являются ObservableCollections.

Это то, что я имею до сих пор:

    /// <summary>
    /// Calls IChangeTracking.AcceptChanges() on all properties of all items in a collection that implement IChangeTracking interface.
    /// </summary>
    internal static void AcceptChangesWithChildren<T>(this ObservableCollection<T> collection) where T : IChangeTracking
    {
        // Calls IChangeTracking.AcceptChanges() on all items in a collection.
        collection.AcceptChanges();

        foreach (T item in collection)
        {
            PropertyInfo[] properties = item.GetType().GetProperties();

            foreach (PropertyInfo property in properties)
            {
                // regular properties that implement IChangeTracking
                if (typeof(IChangeTracking).IsAssignableFrom(property.PropertyType))
                {
                    property.PropertyType.GetMethod("AcceptChanges").Invoke(property, null);
                }

                // Collection of properties that implement IChangeTracking
                if (property.PropertyType.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollection<>)) is Type itemsCollectionType)
                {
                    if (itemsCollectionType.GetGenericArguments().FirstOrDefault(i => typeof(IChangeTracking).IsAssignableFrom(i)) is Type changeTrackingType)
                    {
                        object changeTrackingObject = property.GetValue(item, null);

                        if (changeTrackingObject is IEnumerable<IChangeTracking> changeTrackingEnumerable)
                        {
                            changeTrackingEnumerable.Where(e => e.IsChanged).ForEach(e => e.AcceptChanges());
                        }
                    }
                }
            }
        }
    }

У меня проблема в последнем операторе if. Когда я отлаживаю, changeTrackingObject имеет тип object{System.Collections.ObjectModel.ObservableCollection<SomeClassThatImplementsIChangeTracking>}.

Единственное, что мне удалось привести к этому, было IEnumberable<IChangeTracking>, если я попытаюсь сделать ObservableObject<IChangeTracking> проверку, если блок оценивается как ложный. Есть ли способ разыграть / распаковать changeTrackingObject как ObservableCollection, чтобы я мог вызвать AcceptChangesWithChildren<T>() Рекурсивно?

...