2011-10-20 16 views
7

Scala'da C#'s ExpandoObject benzeri sınıf uygulamasına çalışıyorum. Bu işe gerekiyordu nasıl:Scala'da ExpandoObject Uygulaması

implicit def enrichAny[A](underlying: A) = new EnrichedAny(underlying) 
class EnrichedAny[A](underlying: A) { 
    // ... 
    def dyn = new Dyn(underlying.asInstanceOf[AnyRef]) 
} 

class Dyn(x: AnyRef) extends Dynamic { 
    def applyDynamic(message: String)(args: Any*) = { 
    new Dyn(x.getClass.getMethod(message, 
     args.map(_.asInstanceOf[AnyRef].getClass) : _*). 
     invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*)) 
    } 
    def typed[A] = x.asInstanceOf[A] 
    override def toString = "Dynamic(" + x + ")" 
} 

class ExpandoObject extends Dynamic { 
    private val fields = mutable.Map.empty[String, Dyn] 
    def applyDynamic(message: String)(args: Any*): Dynamic = { 
    fields get message match { 
     case Some(v) => v 
     case None => new Assigner(fields, message).dyn 
    } 
    } 
} 

class Assigner(fields: mutable.Map[String, Dyn], message: String) { 
    def :=(value: Any): Unit = { 
    fields += (message -> value.dyn) 
    } 
} 

Bu kodu derlemeye çalıştığımda, bir StackOverflowError olsun:

İşte
val e = new ExpandoObject 
e.name := "Rahul" // This inserts a new field `name` in the object. 
println(e.name) // Accessing its value. 

Ben şimdiye kadar denedim budur. Lütfen bu işi almama yardım et. :) Teşekkürler.

cevap

4

Biraz oyun oynadıktan sonra çalışıyorum. Çözüm, (bu durumda önemli değildir, bu küçük yardımcı programın noktası tür sistem etrafında çalışmak olduğu için önemli değildir.) Çözüm değildir.

trait ExpandoObject extends Dynamic with mutable.Map[String, Any] { 
    lazy val fields = mutable.Map.empty[String, Any] 
    def -=(k: String): this.type = { fields -= k; this } 
    def +=(f: (String, Any)): this.type = { fields += f; this } 
    def iterator = fields.iterator 
    def get(k: String): Option[Any] = fields get k 
    def applyDynamic(message: String)(args: Any*): Any = { 
    this.getOrElse(message, new Assigner(this, message)) 
    } 
} 

implicit def anyToassigner(a: Any): Assigner = a match { 
    case x: Assigner => x 
    case _ => sys.error("Not an assigner.") 
} 

class Assigner(ob: ExpandoObject, message: String) { 
    def :=(value: Any): Unit = ob += (message -> value) 
} 
+0

Kullanım örneği verebilir misiniz? –

+0

Benim özel durumumda, derleme zamanında hiçbir şey bilmediğim Excel sayfalarında bazı yapısal verileri işlemek zorundayım. Bu verileri dil seviyesi kayıtları olarak ele almak, işlemeyi kolaylaştırır. – missingfaktor

+0

Daha fazla örnek için yukarıdaki bağlantılı makaleye başvurabilirsiniz. – missingfaktor