可逆操作

操作要可逆,当然的首先有操作的接口。
namespace HXZ.Modes.Reversible

{

    /// <summary>

    /// 定义一个方法,该方法是可执行的

    /// </summary>

    public interface IOperable

    {

        void Do();

    }

}
一个可逆的操作和它的逆操作是互相可逆的
namespace HXZ.Modes.Reversible

{

    /// <summary>

    /// 定义一个操作和另一个操作互为可逆操作的类

    /// </summary>

    public class ReversibleOperation

    {

        IOperable _Operation;

        private ReversibleOperation _ReverseOperation;

        public IOperable Operation

        {

            get

            {

                return _Operation;

            }

        }

        /// <summary>

        /// 逆对象

        /// </summary>

        public ReversibleOperation ReverseOperation

        {

            get

            {

                return _ReverseOperation;

            }

        }

        private ReversibleOperation(IOperable operation)

        {

            _Operation = operation;

        }

        /// <summary>

        /// 创建对象的唯一方法

        /// </summary>

        /// <param name="operation"></param>

        /// <param name="reverseOperation"></param>

        /// <returns></returns>

        public static ReversibleOperation CreateObject(IOperable operation, IOperable reverseOperation)

        {

            if (operation == null)

                throw new ArgumentNullException("operation can't be null");

            if (reverseOperation == null)

                throw new ArgumentNullException("reverseOperation can't be null");

            ReversibleOperation reversibleOperation = new ReversibleOperation(operation);

            ReversibleOperation reverseReversibleOperation = new ReversibleOperation(reverseOperation);

            reversibleOperation._ReverseOperation = reverseReversibleOperation;

            reverseReversibleOperation._ReverseOperation = reversibleOperation;

            return reversibleOperation;

        }

    }

}
一个可逆的操作的堆栈和它的逆操作的堆栈是互成可逆的
namespace HXZ.Modes.Reversible

{

    /// <summary>

    /// 一个存放大量ReversibleOperation的操作类

    /// </summary>

    public class ReversibleOperationStack

    {

        private Stack<ReversibleOperation> _OperationStack;

        private ReversibleOperationStack _ReverseStack;

        public int Count

        {

            get

            {

                return _OperationStack.Count;

            }

        }

        protected ReversibleOperationStack()

        {

            _OperationStack = new Stack<ReversibleOperation>();

        }

        /// <summary>

        /// 创建一个ReversibleOperationStack对象

        /// </summary>

        /// <returns></returns>

        public static ReversibleOperationStack CreateObject()

        {

            ReversibleOperationStack operationStack = new ReversibleOperationStack();

            ReversibleOperationStack reverseOperationStack = new ReversibleOperationStack();

            operationStack._ReverseStack = reverseOperationStack;

            reverseOperationStack._ReverseStack = operationStack;

            return operationStack;

        }

        public void Push(ReversibleOperation operation)

        {

            _OperationStack.Push(operation);

        }

        /// <summary>

        /// 取出存放在堆栈中的一条ReversibleOperation执行其Operation.Do方法,

        /// 并将其ReverseOperation存放在_ReverseStack

        /// </summary>

        public void Do()

        {

            ReversibleOperation reversibleOperation = _OperationStack.Pop();

            reversibleOperation.Operation.Do();

            _ReverseStack.Push(reversibleOperation.ReverseOperation);

        }

        /// <summary>

        /// 调用其逆对象_ReverseStack,执行其Do方法

        /// </summary>

        public void DoReverse()

        {

            _ReverseStack.Do();

        }

        /// <summary>

        /// 取出存放在堆栈中的所有的ReversibleOperation分别执行其Operation.Do方法,

        /// </summary>

        public void DoAll()

        {

            while (Count > 0)

                Do();

        }

        /// <summary>

        /// 调用其逆对象_ReverseStack,执行其DoAll方法

        /// </summary>

        public void DoAllReverse()

        {

            _ReverseStack.DoAll();

        }







    }

}
Ioperable的一个具体实现
namespace HXZ.Modes.Reversible

{

    /// <summary>

    /// 定义引用类型的一个公共方法的类,该类通过实现Ioperable来实现这个公共方法的调用

    /// </summary>

    public class RefObjectMethod : IOperable

    {

        public Object _RefObject;

        //public string _FuncName;

        public MethodInfo _Method;

        public object[] _MethodParams;

        //public Type[] _ParamTypeArray;

        public RefObjectMethod(object operationObject, string funcName)

            : this(operationObject, funcName, new Type[] { }, new object[] { })

        {

        }

        public RefObjectMethod(object operationObject, string funcName, Type[] paramTypeArray, object[] paramArray)

        {

            if (operationObject == null)

                throw new ArgumentNullException("operationObject can't be null");

            if (string.IsNullOrEmpty(funcName))

                throw new ArgumentException("funcName can't be null or String.Empty");

            if (paramTypeArray == null)

                throw new ArgumentNullException("paramTypeArray can't be null");

            if (paramArray == null)

                throw new ArgumentNullException("paramArray can't be null");

            if (paramArray.Length != paramTypeArray.Length)

                throw new ArgumentException("paramArray.Length should equal paramTypeArray.Length,but it isn't");

            for (int i = 0; i < paramTypeArray.Length; i++)

            {

                Type paramType = paramTypeArray[i];

                object param = paramArray[i];

                if (param == null)

                {

                    if (typeof(ValueType).IsAssignableFrom(paramType))

                        throw new ArgumentException(string.Format("paramTypeArray[{0}] is ValueType,so paramArray[{0}] shouldn't be null", i));

                    else if (paramType.IsByRef)

                        throw new ArgumentException(string.Format("paramTypeArray[{0}] is {1} and it is by reference,so paramArray[{0}] shouldn't be null", i, paramType));

                }

                else if (!paramType.IsAssignableFrom(param.GetType()) && (!paramType.IsByRef || !paramType.GetElementType().IsAssignableFrom(param.GetType())))

                    throw new ArgumentException(string.Format("paramTypeArray[{0}] is {1},but paramArray[{0}] isn't {1}", i, paramType));

            }

            MethodInfo mi;

            try

            {

                mi = operationObject.GetType().GetMethod(funcName, paramTypeArray);

                if (mi == null)

                    throw new ArgumentException("mi shouldn't be null");

            }

            catch (Exception e)

            {

                throw e;

            }

            _RefObject = operationObject;

            _Method = mi;

            //_FuncName = funcName;

            //_ParamTypeArray = paramTypeArray;

            _MethodParams = paramArray;

        }

        public void Do()

        {

            _Method.Invoke(_RefObject, _MethodParams);

        }

    }

}

你可能感兴趣的:(操作)