首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

代码中可否对类的某个方法临时改写

2013-10-24 
代码中能否对类的某个方法临时改写?测试代码如下:主程序实例化 ClsAAA,然后执行 aaa.ff() 这个方法。class

代码中能否对类的某个方法临时改写?
测试代码如下:主程序实例化 ClsAAA,然后执行 aaa.ff() 这个方法。
class Program
{
    static void Main(string[] args)
    {
        ClsAAA aaa = new ClsAAA();
        //aaa.ff = ShowNothing;

        aaa.ff();
        Console.ReadKey();
    }

    private void ShowNothing()
    {}
}

class ClsAAA
{
    public void ff()
    {
        Console.WriteLine("OK");
    }
}
请问有没有办法让 ff变为ShowNothing(),这样执行 aaa.ff() 实际是执行ShowNothing,不显示任何东西出来。
[解决办法]

引用:
谢谢大家的回答,不过,我没说它的相关环境,所以造成大家的误解。

我想让它应用于写“单元测试”的代码中。

因为某一个子程序总会调用好几个其它子程序,以前我有一个方案,是用标志(处于测试状态),让某些子程序跳过具体执行,并返回计划的内容,该方案存在许多缺点(比如对原代码的改写等问题)。

现在想在单元测试的代码中如果能临时改写某个类的某个方法,比如我们要测试方法一,它中间调用了方法二,如果我们测试代码中改写了方法二,最简单的就是改为空子程序。这样,我执行方法一,它实际调用的是空方法,而不是方法二,就是说我对方法一的测试,就不会涉及到 方法二。



class Program
        {
            static void Main(string[] args)
            {
                IClsAAA aaa = new ClsAAA();
                //aaa.ff = ShowNothing;

                aaa.ff();
                Console.ReadKey();
            }

            
        }

        interface IClsAAA
        {
            void ff();
        }

        class ClsAAA : IClsAAA
        {
            public void ff()
            {
                Console.WriteLine("OK");
            }
        }

        //在测试代码中
        public TestClsAAA : IClsAAA
        {
            public void ff()
            {
                ShowNothing();
            }
        }

        private void ShowNothing()
        { }

        public void TestClsAAA_ShowNothing()
        { 
            IClsAAA aaa = new TestClsAAA();
            aaa.ff();
        }

        
[解决办法]
nuget code --> Install-Package Moq
public class ClsAAA
{
    public virtual void ff()
    {
        Console.WriteLine("OK");
    }
}
  var mock = new Mock<ClsAAA>();
            mock.Setup(foo => foo.ff()).Callback(() => Console.WriteLine("ShowNothing()"));
 mock.Object.ff();
[解决办法]
比如32位.NET2.0的程序可以这样做
        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] 


        internal struct unionMethod
        {
            internal class point
            {
                public int Point;
            }
            [System.Runtime.InteropServices.FieldOffset(0)]
            public point Point;
            [System.Runtime.InteropServices.FieldOffset(0)]
            public object Method;
        }
        internal unsafe struct methodTarget
        {
            public int* MethodPoint;
            public object Target;
            public int* TargetPoint;
        }
        internal class targetPoint
        {
            public object Target;
        }
        public unsafe abstract class methodWriterBase32<methodType> : IDisposable
        {
            private int* methodPoint;
            private int method;
            public methodWriterBase32(methodType setMethod, methodType getMethod)
            {
                if (setMethod == null 
[解决办法]
 getMethod == null) throw null;
                methodPoint = getPoint(setMethod);
                int* getMethodPoint = getPoint(getMethod);
                if (methodPoint == getMethodPoint) throw null;
                method = *methodPoint;
                *methodPoint = *getMethodPoint;
            }
            protected abstract int* getPoint(methodType method);
            public void Set(methodType method)
            {
                if (method == null) throw null;
                *methodPoint = *getPoint(method);
            }
            public void Dispose()
            {
                if (method != 0)
                {
                    *methodPoint = method;
                    method = 0;
                }
            }
        }
        public sealed unsafe class staticMethodWriter32<methodType> : methodWriterBase32<methodType>
        {
            public staticMethodWriter32(methodType setMethod, methodType getMethod) : base(setMethod, getMethod) { }
            protected override int* getPoint(methodType method)
            {


                Delegate methodDelegate = method as Delegate;
                if (!methodDelegate.Method.IsStatic) throw null;
                unionMethod union = new unionMethod { Method = method };
                return (int*)*((int*)*((int*)union.Point.Point + 4) + 2) + 2;
            }
        }
        public sealed unsafe class methodWriter32<methodType> : methodWriterBase32<methodType>
        {
            public methodWriter32(methodType setMethod, methodType getMethod) : base(setMethod, getMethod) { }
            protected override int* getPoint(methodType method)
            {
                Delegate methodDelegate = method as Delegate;
                if (methodDelegate.Method.IsStatic) throw null;
                unionMethod union = new unionMethod { Method = method };
                int point = union.Point.Point;
                int* methodPoint = (int*)point;
                while (*methodPoint != point) ++methodPoint;
                return (int*)*((int*)*(methodPoint + 2) + 2) + 2;
            }
        }

        class ClsAAA
        {
            public void ff()
            {
                Console.WriteLine("OK");
            }
        }
        class ClsBBB
        {
            public void ff()
            {
            }
        }        static void Main(string[] args)
        {
            ClsAAA aaa = new ClsAAA();
            using (methodWriter32<Action> method = new methodWriter32<Action>(aaa.ff, new ClsBBB().ff))
            {
                aaa.ff();
            }
            Console.ReadKey();
        }

热点排行