In Ruby, we can yield the code block from other scope, in order to optimize the amount of writing code:
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
In C#, we also have yield keyword. Here is the example 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;
}
}
The C# yield seems to be the way to return interim result from the iterative method, as opposed to Ruby's way of literally stamping the entire code block into specified region at runtime.
Is there a similar technique of writting less code in C# using yield keyword? For an instance:
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;
}
}
I don't know Ruby, but it looks like basically you want to pass "some code to execute" - which is typically done in C# with a delegate (or an interface, for a specific meaning of course). As far as I can see, yield
in Ruby is entirely different to yield return
in C#. If you don't have any parameters or a return value, the Action
delegate is suitable. You can then call the method using any approach to create a delegate, such as:
For example:
Foo(() => Console.WriteLine("Called!"));
...
static void Foo(Action action)
{
Console.WriteLine("In Foo");
action();
Console.WriteLine("In Foo again");
action();
}
There's a lot to learn about delegates - I don't have time to go into them in detail right now, unfortunately, but I suggest you find a good book about C# and learn about them from that. (In particular, the fact that they can accept parameters and return values is crucial in various situations, including LINQ.)
See more on this question at Stackoverflow