gpt4 book ai didi

c# - 使用 IronRuby 包装器方法将 block 放入 C#

转载 作者:太空宇宙 更新时间:2023-11-03 11:50:19 25 4
gpt4 key购买 nike

我正在使用 IronRuby 并试图想出一个无缝的方法来将 block 传递给 C#。这个问题是 How to use an IronRuby block in C# 的后续问题这表明 block 不能在 IronRuby 和 C# 之间传递。

我接下来的问题是,是否有一种方法可以使用 Ruby 包装器方法将 block 变成 lambda 或 Proc 对象并将其传递给 C#,从而实现相同的目标?

下面是一些符合我希望能够执行的操作的代码。该代码不起作用,但希望其意图足够清楚。

string scriptText =
@"def BlockTest
result = csharp.BlockTest somehow-pass-the-block ("hello")
puts result
end
BlockTest { |arg| arg + 'world'}";

Console.WriteLine("Compiling IronRuby script.");
ScriptEngine scriptEngine = Ruby.CreateEngine();
ScriptScope scriptScope = scriptEngine.CreateScope();
scriptScope.SetVariable("csharp", new BlockTestClass());
scriptEngine.Execute(scriptText, scriptScope);

C# BlockTest 类是:

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

最佳答案

block 是一个神秘的东西,在 CLR 中并不真正存在。然而,Ruby 确实有一个类似于 CLR 委托(delegate)的 proc

例如,这应该可以正常工作:

C#:

public class SomeClass {
public static void Run(Func<int, int> func) { ... }
}

ruby :

proc = lambda { |i| i + 10 }
SomeClass.Run(proc)

有几种创建新过程的方法(许多人更喜欢 Proc.new,但它的工作方式与 C# 函数不太一样,所以我更喜欢 lambda),但关键点这是:

lambda(和 Proc.new)是一个函数 - 您将一个 block 传递给该函数,它会生成一个新的 Proc 对象,该对象包装 block 。

还有一种方法可以在将 block 传递给函数时将 block 隐式转换为过程,使用 &

ruby :

def each
yield 1
end

相同
def each(&block)
block.call 1
end

& 获取已传递给方法的 block (否则将由 yield 隐式调用)并将其转换为 Proc。一旦它是一个 proc,您就可以传递它,将它粘贴在数组中,或者将它传递给 C#。

因此,要调用 C# 方法,您有两个选择:

  1. 创建一个接受 block 的包装器方法,并使用 & 将其转换为 proc。然后,您可以使用此过程调用底层 C# 方法

  2. 在ruby中使用lambdaProc.new直接创建proc,传递给C#方法。

例子:

C# 代码(常用):

public static class MyClass
{
public static void Print(Func<int, int> converter)
{
Console.WriteLine("1: {0}", converter(1));
}
}

Ruby 代码 1(包装器):

class MyClass
class << self # this is only needed to alias class (static) methods, not for instance methods
alias_method :original_print, :print
end

def self.print(&block)
original_print block
end
end

MyClass.print {|i| i * 10}

Ruby 代码 2(直接):

MyClass.print lambda{|i| i * 10}

关于c# - 使用 IronRuby 包装器方法将 block 放入 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2293279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com