我最近发现一个静态方法声明为:
public class Foo
{
public static Func<HtmlHelper, PropertyViewModel, string> Render = (a, b) =>
{
a.RenderPartial(b);
return "";
};
}
Intellisense 建议用法是(例如):
string s = Foo.Render(htmlHelper, propertyViewModel);
那么下面的内容似乎是等价的:
public static string Render(HtmlHelper a, PropertyViewModel b)
{
a.RenderPartial(b);
return "";
}
A) 第一个样式的名称是什么?我意识到它正在使用 lambda;是 = 标志让我绊倒了。我无法将其标记化 ;)
B) 如果两个代码块是等价的,使用前者比使用后者有什么好处?
最佳答案
好的,为了清楚起见,我将再次写出这两个(并稍微修改方法以使其更短)
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate = (a, b) =>
{
return a.RenderPartial(b);
};
public static string RenderMethod(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
}
首先注意RenderDelegate是(如 S. DePouw 所写),只是使用 lambda 语法编写以下内容的一种奇特方式:
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate =
delegate(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
};
RenderMethod之间的区别和 RenderDelegate是那个RenderMethod是一种方法,wheras RenderDelegate是委托(delegate),或者更具体地说,是委托(delegate)类型的字段。这意味着可以将 RenderDelegate 分配给。
委托(delegate)是一种类型。来自MSDN documentation :
A delegate is a type that defines a method signature, and can be associated with any method with a compatible signature.
本质上,您可以将委托(delegate)视为对方法的引用/指针,但是委托(delegate)指向的方法必须与委托(delegate)所期望的签名相匹配。所以例如 Func<HtmlHelper, PropertyViewModel, string>是一个委托(delegate),期望方法带有签名 string MyMethod(HtmlHelper, PropertyViewModel)因此我们可以像这样将具有该签名的方法分配给该委托(delegate):
RenderDelegate = RenderMethod;
重要的是要注意 Delegate 类型(注意大写 D)和 delegate 关键字(小写 d)之间的区别。在您的示例中,您使用 Func<>通用对象来压缩您的代码,但是它有点模糊这里真正发生的事情。 Func<HtmlHelper, PropertyViewModel, string>是一种继承自 Delegate 的类型,并且您可以使用 delegate 关键字来处理等效类型:
delegate string MyFunction<HtmlHelper helper, PropertyViewModel string>;
static MyFunction RenderDelegate = RenderMethod;
当我们在第一个示例中分配 RenderDelegate 时,我们没有将 RenderDelegate 设置为现有的命名方法,而是声明了一个内联的新方法。这被称为匿名方法并且有效,因为我们能够将代码块(也使用 delegate 关键字声明)作为委托(delegate)参数传递:
回到原来的语法 - 您的示例使用 lambda 语法以一种有趣的方式对匿名委托(delegate)进行 delcare。 Lambda 表达式是声明短内联方法的好方法,这些方法通常在处理列表时使用,例如假设我们想按名称对 HtmlHelper 对象列表进行排序。这样做的方法是将比较两个 HtmlHelper 对象的委托(delegate)传递给列表的排序方法,然后排序方法使用该委托(delegate)对列表中的元素进行比较和排序:
static int MyComparison(HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name);
}
static void Main()
{
List<HtmlHelper> myList = GetList();
myList.Sort(MyComparison);
}
为了避免散布大量的短方法,您可以使用匿名方法来在线删除排序方法。这一点真正有用的是,内联方法可以访问在包含范围内声明的变量:
int myInt = 12;
List<HtmlHelper> myList = GetList();
myList.Sort(
delegate (HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name) - myInt;
});
然而,这仍然是相当多的输入,所以 lambda sytax 诞生了,现在你可以这样做:
List<HtmlHelper> myList = GetList();
myList.Sort((x, y) => {return x.Name.CompareTo(y.Name)});
然而,以这种方式声明“正常”方法对我来说似乎完全没有意义(并且让我的眼睛流血)
委托(delegate)难以置信有用,并且(除其他外)是 .Net 事件系统的基石。一些更多的阅读来清理一下:
关于c# - 有人可以解释这个 C# lambda 语法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2113779/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL