有没有一种方法可以在Ironruby中设置类似于C#对象初始化器语法的属性?

StackOverflow https://stackoverflow.com/questions/9304459

  •  25-10-2019
  •  | 
  •  

我正在使用Ironruby在应用程序中进行一些脚本。

我有很多命令(CLR对象)需要创建和执行,但是大多数命令都需要设置在它们上的属性,并且我想避免将命令分配给变量,以便我可以设置属性。

有没有办法像c#对象那样做 初始化器语法?

有帮助吗?

解决方案

构造CLR对象时没有内置的设置属性的方式,因为它不是Ruby本身的功能。但是,尽管Python也不支持这一点,但 Ironpython确实通过允许将命名参数提供给构造函数来支持它. 。由于Ruby不支持命名参数,因此我们不想执行指定的参数模式,无论是 Hash 作为最后一个论点,或一个块 instance_eval'd反对构造对象,或者人们想出的其他东西。

话虽如此,实施对象初始化器的两种策略均可用纯红宝石编写,而无需在Ironruby中任何特殊的支持。我将描述上面列出的两者,但是如果它们不是您要寻找的语法,请随时进行实验。

假设以下CLR类(用C#编写):

namespace TestLib {
  public class TestObj1 {
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
  }
}

您可以想象将属性传递给构造函数的初始化属性:

testobj = TestObj1.new do
  self.prop1 = "Prop1 Value"
  self.prop2 = "Prop2 Value"
end

这就是您可以覆盖的方式 TestObj1.new 支持这一点的方法:

class TestObj1
  def self.new(*args, &block)
    obj = super(*args)
    obj.instance_eval &block
    obj
  end
end

因为这实际上 evals对新创建的对象的块,您可以在块内执行任何Ruby代码。在Ruby中创建DSL和更自然的API时,这种模式很受欢迎。

或者,如果您愿意使用Ruby的宽松 Hash 方法参数中的语法:

testobj = TestObj1.new :prop1 => "Prop1 value", :prop2 => "Prop2 value"

那么这就是您可以覆盖的方式 .new 方法:

class TestObj1
  def self.new(*args)
    last_arg = args[-1]
    if last_arg.kind_of?(Hash)
      first_args = args[0..-2]
      obj = super(*first_args)
      last_arg.each do |prop, val|
        obj.send("#{prop}=", val)
      end
      return obj
    end
    super(*args)
  end
end

Hash 选项绝对更复杂,但性能更高(因为它避免了 eval),是Ruby中更常见的模式,可以暴露命名参数。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top