private _propertyTree CreatePropertyTree(Expression exp, _propertyTree child = null)
        {
            var mExp = exp as MemberExpression;

            if (mExp == null)
            {
                return(null);
            }

            var pi = mExp.Member as PropertyInfo;

            if (pi == null)
            {
                throw new ArgumentException("式木からプロパティを取得できません。");
            }

            var tree   = new _propertyTree(pi, child);
            var parent = CreatePropertyTree(mExp.Expression, tree);

            if (parent != null)
            {
                return(parent);
            }

            return(tree);
        }
        private IDisposable createChildWeakEventListener <TChild>(PropertyTreeChangedWeakEventListener <TChild> listener, _propertyTree tree, PropertyChangedEventHandler handler)
            where TChild : INotifyPropertyChanged
        {
            Action createCldLstnr = null;
            Action dispCldLstnr   = null;

            if (tree != null)
            {
                var methodName = MethodBase.GetCurrentMethod().Name;
                createCldLstnr = () => {
                    var pi         = tree.PropertyInfo;
                    var getterMi   = pi.GetGetMethod();
                    var getterType = typeof(Func <,>).MakeGenericType(pi.ReflectedType, pi.PropertyType);
                    var childValue = Delegate
                                     .CreateDelegate(getterType, getterMi)
                                     .DynamicInvoke(listener._eventSrc);

                    // プロパティに対してリスナーを作成。
                    var    childType     = childValue.GetType();
                    object childListener = null;
                    if (typeof(INotifyPropertyChanged).IsAssignableFrom(childType))
                    {
                        childListener = typeof(PropertyTreeChangedWeakEventListener <>)
                                        .MakeGenericType(childType)
                                        .GetConstructor(new Type[] { childType })
                                        .Invoke(new object[] { childValue });
                        dispCldLstnr = () => {
                            (childListener as IDisposable)?.Dispose();
                        };
                        listener
                        .GetType()
                        .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
                        .MakeGenericMethod(childType)
                        .Invoke(listener, new object[] { childListener, tree.Child, handler });
                    }
                };
            }
            createCldLstnr?.Invoke();
            return(new LivetWeakEventListener <PropertyChangedEventHandler, PropertyChangedEventArgs>(
                       h => new PropertyChangedEventHandler(h),
                       h => {
                _eventSrc.PropertyChanged += h;
            },
                       h => {
                _eventSrc.PropertyChanged -= h;
                dispCldLstnr?.Invoke();
            },
                       (s, e) => {
                if (e.PropertyName == tree.PropertyInfo.Name)
                {
                    handler(s, e);
                    dispCldLstnr?.Invoke();
                    createCldLstnr?.Invoke();
                }
            }));
        }
 public _propertyTree(PropertyInfo pi, _propertyTree child)
 {
     PropertyInfo = pi;
     Child        = child;
 }