如何通过C#方法使用IronRuby块 [英] How to use an IronRuby block with a C# method

查看:74
本文介绍了如何通过C#方法使用IronRuby块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用IronRuby,并试图弄清楚如何通过C#方法使用块.

I'm using IronRuby and trying to work out how to use a block with a C# method.

这是我尝试模仿的基本Ruby代码:

This is the basic Ruby code I'm attempting to emulate:

def BlockTest ()
  result = yield("hello")
  puts result
end

BlockTest { |x| x + " world" }

我尝试用C#和IronRuby做同样的事情是

My attempt to do the same thing with C# and IronRuby is:

 string scriptText = "csharp.BlockTest { |arg| arg + 'world'}\n";
 ScriptEngine scriptEngine = Ruby.CreateEngine();
 ScriptScope scriptScope = scriptEngine.CreateScope();
 scriptScope.SetVariable("csharp", new BlockTestClass());
 scriptEngine.Execute(scriptText, scriptScope);

BlockTestClass是:

The BlockTestClass is:

public class BlockTestClass
{
    public void BlockTest(Func<string, string> block)
    {
        Console.WriteLine(block("hello "));
    }
}

运行C#代码时,出现以下异常:

When I run the C# code I get an exception of:

错误的参数数量(0表示1)

wrong number of arguments (0 for 1)

如果我将IronRuby脚本更改为以下脚本,那么它将起作用.

If I change the IronRuby script to the following it works.

 string scriptText = "csharp.BlockTest lambda { |arg| arg + 'world'}\n";

但是如何使它与原始IronRuby脚本一起使用,使其与我的原始Ruby示例等效?

But how do I get it to work with the original IronRuby script so that it's the equivalent of my original Ruby example?

 string scriptText = "csharp.BlockTest { |arg| arg + 'world'}\n";

推荐答案

Ruby的块不是c#(或任何其他.Net语言)理解的概念.

Ruby's blocks are not a concept understood by c# (or any of the other .Net languages).

要将传递一个"到委托人的c#中类似的概念,必须将其包裹"在可以理解的地方.

To 'pass one' to the similar concept in c# of the delegate you must 'wrap it' in something that is understandable.

通过使lambda超出代码块,您可以将其传递给需要委托或表达式的C#代码.

By making a lambda out of the block it becomes something you can pass to c# code expecting a delegate or expression.

这是'Alt.Net'社区的常见问题,即使对于f#这样的受祝福的语言,其中的函数指针"并未实现为委托,而是通过稍有不同的方式(例如,f#中的FastFunc实例)来传递.将这些内容转换为类似于c#示例的内容时,需要将其包装在一个委托中(实际上是创建一个委托,该委托的调用将参数传递给底层实例,然后将结果返回).

This is a common issue with the 'Alt.Net' community, even for blessed languages like f# where 'functions pointers' are not implemented as delegates but instead are done slightly differently (FastFunc instances in f# for example) to pass one of these to something like your c# example would require wrapping it in a delegate (literally creating a delegate whose invocation passes the parameters to the underlying instance and returns the result back).

有人可能会说,如果这种翻译是自动的,那么翻译会更好,但是这样做会导致复杂而奇怪的边缘情况或错误,许多开发人员更愿意仅通过查看代码就知道会发生这种包装操作.在某些情况下,不一定总是有合理的转换(或存在多个转换),因此让用户决定发生什么是明智的默认设置.

One could argue that such translation would be nicer if it was automatic, but doing that can lead to complex and strange edge cases or bugs and many developers prefer to know that such a wrapping operation will occurred just by looking at the code. It is also the case that there may not always be reasonable conversion (or more than one exists) so making the user decide what happens is a sensible default.

这篇关于如何通过C#方法使用IronRuby块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆