var data = db.Query(sql).OrderByDescending(c => c.DatePosted);
这种事情似乎跟我追尾……
为什么c => C.必要?以下是不可理解的(编译器,人类更是如此)?
var data = db.Query(sql).OrderByDescending(DatePosted);
我确信在幕后发生了各种奇特的事情,据称需要这种奇怪的lambda语法,但同样:
为什么?真的有必要吗?编译器不能弄清楚DatePosted是要排序的列吗?
解决方法
…why is the @H_403_20@c => c. necessary? Wouldn’t the following be understandable (by the compiler,and even more so by humans…
首先,如果您希望您的查询可供人类阅读并删除lambda,则使用人类可读的语法编写查询并省略lambda:
query = from record in records orderby record.DatePosted descending select record;
我更喜欢这种语法的原因:它更容易阅读,它强调业务领域中查询的语义,而不是订购机制需要密钥选择功能的事实.
其次,c => c.没有必要.假设你有一个方法:
static DateTime DatePosted(Record record) { return record.DatePosted; }
现在使用您想要的语法是完全合法的:
records.OrderByDescending(DatePosted)
编译器将推断出DatePosted是调用以获取排序键并适当地构造委托的函数. (请注意,它也会正确推断出类型,并确定您的意思是OrderByDescending< Record,DateTime> ;.) 更一般地说:C#的基本设计原则是语言不会猜测你的意思,除非在某些非常明确的情况下(*).查询可以按字面意义排序,因此,代码的作者应该清楚地说明排序键是什么.在查询语法中,表示集合元素的范围变量可用,以便您可以轻松地表达“按与每个记录关联的日期排序”.只是说“按日期排序”将涉及进行猜测. 对于lambda语法,该方法需要一个选择顺序键的函数.您可以提供所需的函数,方法是提供委托类型的值,可转换为委托类型值的lambda,或者可转换为委托类型值的方法组. “裸”财产不是一种功能. 那么,C#语言是否可以设计成当你提供一个属性的名称而没有任何上下文解释它的属性时,编译器会猜测?它说“哦,我看到这里有一个名为OrderBy的方法,它接受一个函数和一个序列,让我猜一下,为函数提供的名称是函数”从给定的元素中取出这个属性顺序“?当然,我本可以这样做.代码写起来并不那么难.但这不符合C#语言的设计原则.保存几次按键的好处不值得痛苦违反设计原则,意图在代码中明确陈述. (*)与隐式类型的局部变量,方法类型推断,隐式类型数组和重载分辨率一样,所有这些都涉及编译器最好地猜测开发人员的意图.做出这些猜测的规则是经过仔细记录的,并且经过精心设计,如果检测到任何歧义,大多数人都会提前纾困.