2011-10-20 69 views
7

我想實現在Scala中C#'s ExpandoObject般類。這是它是如何工作的:實施ExpandoObject斯卡拉

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

這裏是我到目前爲止已經試過:

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) 
    } 
} 

當我嘗試編譯這段代碼,我得到一個StackOverflowError。請幫我完成這項工作。 :) 謝謝。

回答

4

明白了一些玩了之後的工作。該解決方案不是類型安全的(在這種情況下並不重要,因爲這個小實用程序的意義在於在類型系統上工作。:-)

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

您能給出一個用法示例嗎? –

+0

在我的具體情況,我必須處理Excel表格,我知道在編譯時沒有的一些結構化的數據。將這些數據視爲語言級記錄使處理變得更簡單。 – missingfaktor

+0

您可以參考上面鏈接的文章以獲取更多示例。 – missingfaktor