CSharp - 滥用C# lambda表达式或者语法?

  显示原文与译文双语对照的内容

我查看了 MvcContrib 网格组件,我着迷了,但同时,repulsed使用了网格语法中使用的语法技巧:


.Attributes(style =>"width:100%")

上面的语法将生成的HTML的样式属性设置为 width:100% 。 现在,如果你注意,'风格'没有指定,它是从表达式中参数的推断出来的 ! 我不得不深入探索'魔幻'发生的地方:


 Hash(params Func<object, TValue>[] hash)
 {
 foreach (var func in hash)
 {
 Add(func.Method.GetParameters()[0].Name, func(null));
 }
 }

因此,代码正在使用正规,编译时间,参数名称来创建属性name-value对字典。 所产生的语法构造的确很有表现力,但同时非常危险。 一般允许使用lambda表达 ofthe更换for所用名称无side效果。 我在书上看到一个例子 collection.ForEach(book => Fire.Burn(book)) 我知道我可以写我的代码 collection.ForEach(log => Fire.Burn(log)) 它意味着同样的东西。 但是,在这里使用MvcContrib网格语法,突然我发现了一个代码,它根据我为变量选择的名称主动查找并生成 decissions !

C# 3.5/4.0 社区和lambda表达式爱好者的共同实践? 或者是一个无赖的诡计,我不应该担心?

时间:

这里操作的互操作性较差。例如考虑这里 C# - F# 示例

C#:


public class Class1
{
 public static void Foo(Func<object, string> f)
 {
 Console.WriteLine(f.Method.GetParameters()[0].Name);
 }
}

F#


Class1.Foo(fun yadda ->"hello")

结果:

""打印( 而不是打印)"yadda") 。

因此,库设计者应该避免这种类型的'滥用项',或者至少提供一个'标准'重载( 例如。 如果要在. NET 语言之间有良好的互操作,那么就把字符串名称作为额外的参数。

其说我发现奇怪因为的名字,而是因为λ是不必要的;它可以用一个anonymous-type和更灵活的:


.Attributes(new { style ="width:100%", @class="foo", blip=123 });

这是一个模式中使用的大部分 ASP.NET MVC ( 例如), 并且其他用途 ( 警告,还要注意思想ayende如果名称是一个魔力值而不是 caller-specific )

这是可怕在不止一个级别。 不,这跟 ruby 没什么关系。 这是对 C# 和. Net.的滥用

有许多关于如何以更直接的正向方式执行这里操作的建议: 元组,匿名类型,连贯接口等。

使它如此糟糕的原因是它只是为自己的优点而设计的:

  • 当你需要从VB调用这个时,会发生什么?

    .Attributes(Function(style)"width:100%")

  • 它完全是直观的,智能感知将提供很少的帮助,找出如何通过。

  • 它不必要的低效率。

  • 没有人知道如何维护它。

  • 进入属性的参数的类型是什么,是 Func<object,string>? 这意味着什么。 你的智能感知文档会说什么,"请忽略对象的所有值"

我认为你对revulsion的感觉完全是合理的。

不,这当然不是普通的做法。 它是 counter-intuitive,没有办法只查看代码来找出它是什么。 你必须知道它是如何用来理解它是如何使用的。

使用委托数组提供属性不同,链接方法将更加清晰并执行更好:


.Attribute("style","width:100%;").Attribute("class","test")

虽然这是更多的类型,但它是清晰和直观的。

...