谈谈LINQ的缺点

简介:

概要:

·LINQ的实质是什么

·LINQ的问题是将复杂的问题简单化,让简单的问题复杂化

·LINQ喧宾夺主:

- Lambda的抽象能力和描述能力大于LINQ

扩展方法给程序员带来的好处也是强于LINQ

·目前C#中的Lambda和扩展方法是半完成的半吊子状态

 

上面这些观点我以前的随笔中也出现过,这次乘着讨论LINQ的东风,详细深入的讨论一下。

 

1 LINQ的实质是什么

在远古时代,编程等于数据结构加算法,在现今时代,编程等于实体加策略。LINQ是一种接近于自然语言的针对Collection的策略(叫delegate也好,Functor也好)组合的描述。

- LINQ可能(非可以!)节省代码量

- LINQ可能(非可以!)具备更加的可读性

- LINQ仅限于对Collection的操作

 

2 LINQ的问题是将复杂的问题简单化,让简单的问题复杂化

对于简单的策略组合问题,Lambda加上静态方法以及Collection的原有方法,可以提供和LINQ一样简单的、可读性一样好的解决方案。据说MSDN上不提倡直接用LINQ命名空间下的扩展方法,不过我觉得在大多数情况下直接用这些扩展方法比直接用LINQ更直接明了。

对于复杂的策略组合问题,LINQ是有优势的,可以将复杂的集合操作简单化。

问题在于:

i)在程序开发中,绝大部分对Collection的操作都是简单操作,这些操作LINQ相比Lambda+现有方法+扩展方法并没有优势

ii)少部分对Collection的复杂操作一般来说都是需要封装的,对外提供简单的接口调用。这些部分,用LINQ会有优势。不过,LINQ的描述能力还是有限的,很多更复杂的操作,LINQ描述不了。对于我来说,这样的需求已经好几个项目没遇上过了,遇上的话,用硬编码所花的时间也可以接受,不必要花时间去学LINQ

 

3LINQ的喧宾夺主问题

LINQ的光芒将Lambda表达式和扩展方法给掩盖住了,有点喧宾夺主的味道。如果让我来区分几个之间的区别,Lambda表达式和扩展方法应该属于战略层面的扩展,LINQ属于战术层面的。

先看Lambda表达式,Lambda表达式天生就是描述策略组合的,它的可读性和LINQ差不多,它的描述能力却比LINQ强大很多,它和图灵机是等价的,而LINQ背后的关系数学的计算能力是很有限的。

再看扩展方法。不知道大家是否还记得这个词:AOP。现实中,AOP的讨论大多集中于实做成面而不是思想层面。从思想层面来说,AOP就是将相关的东西通过某种方式集中的展现与处理。比如说,我们在IDE中,输入一个变量,再输入一个“.”,那么关于这个变量的操作就集中的展现给我们任由我们选择,这一点我觉得也应该属于AOP

在编码当中,很多时候我们需要对一个类进行修饰,这些修饰类一多的时候,很难集中处理,我们经常忘记有哪些修饰类,修饰类之间的公用也不好处理。扩展方法使我们能够以AOP的范式来对类和对象进行修饰。在IDE中,我们一打“.”,这些修饰就AOP的展示给我们了。扩展方法还可以有一些更激进的应用,只不过微软目前没给我们。

 

4C#目前Lambda表达式和扩展方法的不足之处

目前C#Lambda表达式处于太监状态:不能推演类型。这样一来,撰写复杂的策略操作组合时需要写很长很长,嵌套一层又一层的类型定义,如此在复杂的策略组合时,使用Lambda表达式就很费事了。真不知道M$怎么想的,难道是给F#留路子?

扩展方法的遗憾之处是没法对属性进行扩展,我不熟悉CLR底层实现,但如果能对属性进行扩展,然后使用某种机制使扩展方法和扩展属性在反射层面也能被当作一般属性和一般方法进行处理就更好了。这样的话,几乎全部的对类的修饰都可以通过扩展方法来进行。倒是向动态语言靠拢了。恩,等4.0再看看。

 

俺的选择:

结合以上讨论,俺在工作中是放弃应用LINQ了。主要觉得花费那时间去学习,所节省的时间未必有学习花的时间多。Lambda表达式和扩展方法倒是用的挺多。

俺迫切需要动态代理功能。别人都是AOP需要,俺是在用泛型时需要。

比如,Winform下的 ToolStripComboBox  ComboBox 类,很多方法和属性名称一样,我需要取出一些值,将这些值绑定到ToolStripComboBoxComboBox上。这些值可能有1000多个,因此只在***BoxItem中绑定最常见的几个,然后再加上一条“选择其它”。为此,我需要写两份几乎一模一样的代码,邪恶啊。。。。。。ToolStripComboBox  ComboBox 没有公共接口,不用反射没法搞啊,用反射。。。,俺还是复制粘贴吧。

俺需要这样的一种动态代理:

假定有一个接口:

     public   interface  TInterface
    {
        String A { 
get set ; }
        String B();
    }

 

一个类

复制代码
     public   class  ClassA
    {
        
public  String A {  get set ; }
        
public  String B()
        {
            
return  String.Empty;
        }
    }
复制代码

 

和一个类工厂:

复制代码
     public   sealed   class  TypeTemplate
    {
        
public   static  T Create < T > (Object instance)  where  T :  class
        {
            
        }
    }
复制代码

 

这个代理类可以用一个动态生成的类的实例将ClassA实例打包一下,使其适应Tinterface。这样来弥补C#的泛型不能实现编译时多态的问题,来减少代码的重复,可以充分发挥出泛型的威力了。

更进一步,如果动态类与被代理的类的属性和方法签名不一致的话,能够手动添加之间的映射关系,实用性就更强了。

关于策略的组合,设计模式中策略模式是一种做法。泛型编程中泛型是另一种做法。Lambda表达式是另外一种做法。目前C#的泛型、Lambda深入应用的话,总是缺点什么。不爽。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2009/01/06/1369945.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关文章
|
4月前
|
存储 测试技术 数据库
谈谈代码:降低复杂度,从放弃三层架构到DDD入门
最近我发现团队某项目的复杂度越来越高(典型的三层架构),具体表现为: - 代码可读性较差:各个服务之间调用复杂,流程不清晰 - 修改某服务业务代码导致大量无关服务的测试用例失败,单个功能开发者很难迅速定位相关问题 - 测试用例特别难编写,需要mock大量数据来拉起整块服务
102 4
谈谈代码:降低复杂度,从放弃三层架构到DDD入门
|
4月前
|
XML JSON 前端开发
前端深浅拷贝各有哪些方法,优缺点
前端深浅拷贝各有哪些方法,优缺点
37 0
|
6月前
|
Java
Java多线程编程的优点和缺点
优点: 加快响应用户的时间:多线程允许并发执行多个任务,可以充分利用多核处理器,从而提高程序的性能和响应速度。比如我们经常用的迅雷下载,都喜欢多开几个线程去下载,谁都不愿意用一个线程去下载,为什么呢?答案很简单,就是多个线程下载快啊。 简化程序结构、模块化、异步化:例如我们实现电商系统,下订单和给用户发送短信、邮件就可以进行拆分,将给用户发送短信、邮件这两个步骤独立为单独的模块,并交给其他线程去执行。这样既增加了异步的操作,提升了系统性能,又使程序模块化,清晰化和简单化。 更好的资源利用:多线程可以更有效地使用计算机的资源,如CPU时间、内存和文件句柄等,提高了资源利用率。 支持并发编程:多线
740 0
|
8月前
|
Web App开发 JavaScript 前端开发
前端优化的几种方法和底层原理
前端优化的几种方法和底层原理
|
9月前
如何理解ALU的优点?
ALU是组合逻辑电路!
163 0
模型驱动是什么意思?底层原理是什么?
模型驱动是什么意思?底层原理是什么?
733 0
|
Java Linux Go
新语言你确定,不比较下优缺点么
新语言你确定,不比较下优缺点么
133 0
|
Kubernetes 监控 安全
[k8s]谈谈 k8s 的本质
当下 k8s 算是比较火的一个内容,那么它到底是什么呢,它为什么会这么火呢,它解决的是什么问题呢. 当我们谈 k8s 的时候,总是会想起来 Docker .是的,如果想要知道 k8s 解决的是什么问题,我们不可避免的再回到 Docker 上面,回到容器上面来.
[k8s]谈谈 k8s 的本质
|
API 开发者 C#
带你读《More Effective C#:改善C#代码的50个有效方法》之二:API设计
本书围绕一些关于C#和.NET的重要主题,包括C#语言元素、.NET资源管理、使用C#表达设计、创建二进制组件和使用框架等,讲述了最常见的50个问题的解决方案,为程序员提供了改善C#和.NET程序的方法。本书通过将每个条款构建在之前的条款之上,并合理地利用之前的条款,来让读者最大限度地学习书中的内容,为其在不同情况下使用最佳构造提供指导,适合各层次的C#程序员阅读。