在Ruby中,我们可以从其他范围产生代码块,以优化编写代码的数量:
def get_resource(published=true)
find_resources do
if I18n.locale == :ar && @resource_slug == "home"
Resource.find_by_slug("home")
else
ResourceType.find_by_slug(@type_slug).resources.send(
published ? :published : :unpublished
).find_by_slug(@resource_slug)
end
end
end
def get_resources(published=true)
find_resources do
ResourceType.includes(:resources).find_by_slug(@type_slug).resources.send(
published ? :published : :unpublished
)
end
end
def find_resources
begin
@type_slug, @resource_slug = params[:type], params[:resource]
yield
rescue Mongoid::Errors::DocumentNotFound, NoMethodError
nil
end
end
在C#中,我们还有yield关键字。以下是示例taken from documentation:
//using System.Collections;
//using System.Diagnostics;
public static void Process()
{
// Display powers of 2 up to the exponent of 8:
foreach (int number in Power(2, 8))
{
Debug.Write(number.ToString() + " ");
}
// Output: 2 4 8 16 32 64 128 256
}
public static IEnumerable Power(int baseNumber, int highExponent)
{
int result = 1;
for (int counter = 1; counter <= highExponent; counter++)
{
result = result * baseNumber;
yield return result;
}
}
C#yield似乎是从迭代方法返回中间结果的方法,而不是Ruby在运行时将整个代码块压缩到指定区域的方式。
是否有类似的技术使用yield关键字在C#中编写更少的代码?例如:
public class EntityBase
{
// Generic Try-Catch function, so we never have to write this block in our code
public object GenericTryCatch()
{
try
{
// yield here
}
catch(Exception except)
{
Logger.log(except.Message);
}
finally
{
// return the control to the caller function
}
return null;
}
}
答案 0 :(得分:4)
我不知道Ruby,但看起来基本上你想要传递“一些代码来执行” - 这通常是在C#中使用委托(或接口,当然是特定含义)来完成的。据我所知,Ruby中的yield
与C#中的yield return
完全不同。如果您没有任何参数或返回值,则Action
委托是合适的。然后,您可以使用任何方法调用该方法来创建委托,例如:
例如:
Foo(() => Console.WriteLine("Called!"));
...
static void Foo(Action action)
{
Console.WriteLine("In Foo");
action();
Console.WriteLine("In Foo again");
action();
}
有很多关于代表的知识 - 不幸的是,我现在没有时间详细介绍它们,但我建议你找一本关于C#的好书并从中了解它们。 (特别是,它们可以接受参数和返回值这一事实在各种情况下都很重要,包括LINQ。)
答案 1 :(得分:4)
我对Ruby的有限知识告诉我你只想要某种代表:
void SomeMethod(Action action) {
// do some stuff here
action(); // the equivalent (that I can see) of yield
}
用法:
SomeMethod(() => {
// method that is called when execution hits "action()" above
});