Xorcerer 发表于 2013-2-5 01:17:22

C#用反射实现类似单元测试中的自动调用测试方法。

在微软的单元测试中,每个测试方法,只要打上一个attribute(属性?不知道怎么翻译了)——TestMethod,就可以自动被调用。
最近公司需要针对某些类写一一对应的检测类,检测对应类的数据正确性。为了方便,我写了一个支持泛型的基类Checker<Type>,放置通用代码。
第一版的程序如下:
public class Checker<Type>      where Type: HomeObject    {      public bool Check( Type hObject )      {            foreach ( MethodInfo method in this.GetType().GetMethods().Where(                m =>                  m.GetCustomAttributes( true ).Where(                        attr => attr is CheckMethodAttribute                        ).Count() > 0 ) )            {                if ( !(bool)method.Invoke( this, new object[] { hObject } ) ) return false;            }            return true;      }    }
这样每次运行Check函数,就可以自动调用带有CheckMethod的方法了。这些方法各自定义了一些独立的规则,格式都是boolean func(Type obj)。
请注意,上面提到一个CheckMethodAttribute,只需要一个空壳。
后缀Attribute不是必须的,我只是尊重微软的习惯。
        public class CheckMethodAttribute: Attribute    {      public CheckMethodAttribute()      {      }    }
子类例子如下,
    class JunctionBoxChecker: Checker<JunctionBox>    {            public bool IsInterior( JunctionBox junctionbox )      {            //Some Code......            return surface.IsInterior;      }            public bool NotTooCloseWithOthers( JunctionBox junctionbox )      {            //Some Code......            return boolValue;      }    }
这里有个小问题,那就是每次运行Check()时,都要搜索一次带有指定Attribute的方法,而其实所有的方法在编译之后,都是确定了的。
所以,更有效的写法是,其实可以在类中用一个静态的List来保存上面的方法的引用,该List在静态构造器中初始化和确定值。这里用到了C#的一个特性,Checker<ClassA>,Checker<ClassB>被当做两个类,所以,里面的静态List不冲突。
页: [1]
查看完整版本: C#用反射实现类似单元测试中的自动调用测试方法。