C# 程序员最常犯的 10 个错误(3)

#5常见错误:在LINQ语句之中没有考虑底层对象

对于处理抽象操纵集合任务,LINQ无疑是庞大的。无论他们是在内存的对象,数据库表,或者XML文档。在如此一个完美世界之中,你不需要知道底层对象。然而在这儿的错误是假设我们生活在一个完美世界之中。事实上,相同的LINQ语句能返回不同的结果,当在精确的相同数据上执行时,如果该数据碰巧在一个不同的格式之中。

例如,请考虑下面的语句:

decimal total=(from accout in myaccouts
where accout.status==‘active"
                  select accout .Balance).sum();

想象一下,该对象之一的账号会发生什么。状态等于“有效的”(注意大写A)?

好吧,如果myaccout是Dbset的对象。(默认设置了不同区分大小写的配置),where表达式仍会匹配该元素。然而,如果myaccout是在内存阵列之中,那么它将不匹配,因此将产生不同的总的结果。

等一会,在我们之前讨论过的字符串比较中, 我们看见 == 操作符扮演的角色就是简单的比较. 所以,为什么在这个条件下, == 表现出的是另外的一个形式呢 ?

答案是,当在LINQ语句中的基础对象都引用到SQL表中的数据(如与在这个例子中,在实体框架为DbSet的对象的情况下),该语句被转换成一个T-SQL语句。然后遵循的T-SQL的规则,而不是C#的规则,所以在上述情况下的比较结束是不区分大小写的。

一般情况下,即使LINQ是一个有益的和一致的方式来查询对象的集合,在现实中你还需要知道你的语句是否会被翻译成什么比C#的引擎或者是其他表达,来确保您的代码的行为将如预期在运行时。

常见错误 #6:对扩展方法感到困惑或者被它的形式欺骗

如同先前提到的,LINQ状态依赖于IEnumerable接口的实现对象,比如,下面的简单函数会合计帐户集合中的帐户余额:

public decimal SumAccounts(IEnumerable<Account> myAccounts) { return myAccounts.Sum(a => a.Balance); }

在上面的代码中,myAccounts参数的类型被声明为IEnumerable<Account>,myAccounts引用了一个Sum 方法 (C# 使用类似的 “dot notation” 引用方法或者接口中的类),我们期望在IEnumerable<T>接口中定义一个Sum()方法。但是,IEnumerable<T>没有为Sum方法提供任何引用并且只有如下所示的简洁定义:

public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }

但是Sum方法应该定义到何处?C#是强类型的语言,因此如果Sum方法的引用是无效的,C#编译器会对其报错。我们知道它必须存在,但是应该在哪里呢?此外,LINQ提供的供查询和聚集结果所有方法在哪里定义呢?

答案是Sum并不在IEnumerable接口内定义,而是一个

定义在System.Linq.Enumerable类中的static方法(叫做“extension method”)

namespace System.Linq { public static class Enumerable { ... // the reference here to “this IEnumerable<TSource> source” is // the magic sauce that provides access to the extension method Sum public static decimal Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector); ... } }

可是扩展方法和其它静态方法有什么不同之处,是什么确保我们可以在其它类访问它?

扩展方法的显著特点是第一个形参前的this修饰符。这就是编译器知道它是一个扩展方法的“奥妙”。它所修饰的参数的类型(这个例子中的IEnumerable<TSource>)说明这个类或者接口将显得实现了这个方法。

(另外需要指出的是,定义扩展方法的IEnumerable接口和Enumerable类的名字间的相似性没什么奇怪的。这种相似性只是随意的风格选择。)

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e40bfc959a82c25d181a341c367a7163.html