Gibt es eine Möglichkeit, Eigenschaften in IronSruby ähnlich wie die C# -Objektinitializer -Syntax zu setzen?

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

  •  25-10-2019
  •  | 
  •  

Frage

Ich benutze IronRuby, um in meiner App ein Bild zu machen.

Ich habe viele Befehle (CLR -Objekte), die ich erstellen und ausführen muss, aber die meisten Befehle benötigen Eigenschaften, die auf ihnen festgelegt sind, und ich möchte vermeiden, dass der Befehl einer Variablen zugewiesen wird, damit ich die Eigenschaften festlegen kann.

Gibt es eine Möglichkeit, es wie das C# -Objekt zu tun? Initializer -Syntax?

War es hilfreich?

Lösung

Es gibt keine eingebaute Möglichkeit, Eigenschaften zu setzen, wenn CLR-Objekte erstellt werden, da es sich nicht um Merkmale von Ruby selbst handelt. Obwohl Python dies auch nicht unterstützt, Ironpython unterstützt es, indem benannte Parameter an Konstrukteure geliefert werden können. Da Ruby nicht benannte Parameter unterstützt, wollten wir kein benanntes Parametermuster durchsetzen, sei es a Hash als letzte Argument oder ein Block, der ist instance_evalD gegen das konstrudierende Objekt oder etwas anderes, das sich Menschen einfallen lassen.

Trotzdem können beide Strategien zur Implementierung von Objektinitialisierern in reinem Ruby ohne besondere Unterstützung in Ironruby geschrieben werden. Ich werde beide oben aufgeführt beschreiben, aber ich kann gerne experimentieren, wenn sie nicht genau die Syntax sind, nach der Sie gesucht haben.

Annahme der folgenden CLR -Klasse (geschrieben in C#):

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

Sie können sich vorstellen, Eigenschaften mit einem an den Konstruktor übergebenen Block zu initialisieren:

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

Und hier ist, wie Sie das überschreiben konnten TestObj1.new Methode, um dies zu unterstützen:

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

Da dies eigentlich evalS Der Block gegen das neu erstellte Objekt können Sie jeden Ruby -Code im Block ausführen. Dieses Muster ist bei der Erstellung von DSLs und natürlicheren APIs in Ruby beliebt.

Oder wenn Sie es lieber mit Ruby's Nachfolgend verwenden Hash Syntax in Methodenargumenten:

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

Dann können Sie das überschreiben .new Methode:

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

Das Hash Die Option ist definitiv etwas komplizierter, aber etwas leistungsfähiger (wie sie vermeidet eval) und ist ein häufigeres Muster in Ruby, um benannte Parameter freizulegen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top