示例#1
0
        private bool GetIsChangedDeep(ITrackable trackable, HashSet <object> visited)
        {
            if (trackable == null)
            {
                return(false);
            }

            var trackedObject = trackable is ChangeTracker changeTracker
                ? changeTracker.GetTrackedObject()
                : trackable;

            if (trackedObject == null || visited.Contains(trackedObject))
            {
                return(false);
            }

            visited.Add(trackedObject);

            if (trackedObject != trackable && trackedObject is ITrackable innerTrackable)
            {
                if (innerTrackable.GetIsChanged())
                {
                    return(true);
                }
            }
            else if (trackable.GetIsChanged())
            {
                return(true);
            }

            foreach (var prop in trackedObject.GetType().GetPropertiesEx().Where(x => x.CanGet && x.PropertyInfo.GetIndexParameters().Length == 0))
            {
                if (prop.Type.IsAssignableTo(typeof(ITrackableObject)) &&
                    GetIsChangedDeep(prop.Get(trackedObject) as ITrackableObject, visited))
                {
                    return(true);
                }
                else if (prop.Type.IsAssignableTo(typeof(ITrackableCollection)))
                {
                    if (!(prop.Get(trackedObject) is ITrackableCollection trackableList))
                    {
                        return(false);
                    }

                    if (trackableList.GetIsChanged())
                    {
                        return(true);
                    }

                    if (trackableList.ElementType.IsAssignableTo(typeof(ITrackableObject)))
                    {
                        foreach (ITrackableObject item in trackableList)
                        {
                            if (GetIsChangedDeep(item, visited))
                            {
                                return(true);
                            }
                        }
                    }
                }
                else if (prop.IsEnumerable)
                {
                    foreach (var item in (IEnumerable)prop.Get(trackedObject))
                    {
                        if (item != null && item is ITrackableObject enumeratedTrackable &&
                            GetIsChangedDeep(enumeratedTrackable, visited))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }