zoukankan      html  css  js  c++  java
  • 吹毛求疵C#(2)期待强类型成员信息

    (2)期待强类型成员信息

    CLR4.0为我们带来了新的神器---完整的ExpressionTree, 程序自己可以更方便的写程序了.  什么DSL呀, 运行时代码生成呀, 结合Attribute让编程更声名式等等都方便了很多, 带来了无限的可能性.

    事情是可以做了, 而且未来还可以发展的更好---比如健壮性和性能.

    比如下面这个例子: c#

    class MyType{
        public static void MyFunc(){...}
    } 
    
    
    Expression GenerateSomeExpression(...){
        ...
            Expression.Call(null, typeof(MyType).GetMethod("myFunc",...)//Runtime error! M m
        ...
    }

    首先我们实现了一些自己的API, "MyFunc", 在机器生成的代码中需要调用这些事先写好的函数. 目前的做法是在运行时, 通过函数名的字符串来进行查找. 可以工作, 但存在2个明显的问题:

    1, 编译器本可以检查出一些错误, 但却没有这么做. 比如例子中MyFunc被笔误成了myFunc, 如果没有彻底的单元测试, 很可能在运行时会弹出个让用户莫名其妙的异常. 而且当重构和版本变更时, 也会有麻烦, 这些成员名的字符串不会随着他们所对应的标示符所变化.

    2, 性能, 如果不用多写几行搞个缓存的话, 那么运行时每次都要拿字符串去查找, 又占内存又发热的. 而本来只要在编译时查找一次就可以了的. 缓存可以解决性能问题, 但无疑会降低代码的可读性, 也会增加编码量.

    特别是第一个问题, 在实现有一定规模的DSL时会很烦. 会限制ExpressionTree的使用范围.

    一个切实可行的解决办法是像用typeof()获取Type对象那样, 实现在编译器静态获取类型成员信息的能力. 比如就扩展typeof的能力, 或者增加新关键字, 比如memberof, infoof, fieldof, methodof诸如此类.

    如果能实现, 那么访问这些静态成员信息会舒适的多, 比如像下面这样:

    class MyClass{
      public int _field;
      public void Method(){};
    } 
    
    
    Type type = typeof(MyClass);
    FieldInfo fieldInfo = typeof(MyClass._field);
    MethodInfo method = typeof(MyClass.Method);
    
    
    现在即健壮又高效了. 写错了在编译时即可检查出来, 重构要改名字也准确无误.

    可能会比较有争议的是关于可见性的问题, 我倾向于让typeof()获取成员信息时也受可见性规则约束, 不可见成员还是拿字符串查. 这样能减少对封装的破坏.

    相关链接:https://connect.microsoft.com/VisualStudio/feedback/details/570174/compile-time-member-info#details

  • 相关阅读:
    TP连接数据库报错:SQLSTATE[HY000] [2002] No such file or directory (原)
    linux的查找命令 find whereis locate
    windows下cmd无法使用telnet命令解决方法 (原)
    CDN和智能DNS原理和应用 (原)
    面试:sql语句-1-基础查询
    面试问题:对框架的理解
    Hub,bridge,switch and router的区别
    If you ever have a broken heart
    virt-viewer的简单使用
    各种虚拟化镜像文件格式
  • 原文地址:https://www.cnblogs.com/robird/p/1764390.html
Copyright © 2011-2022 走看看