c# - 在 Scala 中实现 ExpandoObject

标签 c# scala dynamic expandoobject

我正在尝试实现 C#'s ExpandoObject -类似于 Scala 中的类。它应该是这样工作的:

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。请帮我完成这项工作。 :) 谢谢。

最佳答案

经过一些尝试后它开始工作了。尽管该解决方案不是类型安全的(在这种情况下这无关紧要,因为这个小实用程序的目的是解决类型系统问题。:-)

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

关于c# - 在 Scala 中实现 ExpandoObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7832431/

相关文章:

scala - 在 Scala 中消除隐式解析的歧义

c# - .NET 动态方法。最棒的表演

C# 钳形 for 循环

C# XML 数据反序列化 - 基于引用 ID 应用对象关系

c# - Asp .Net Core 为什么即使用户未通过身份验证也会调用我的授权处理程序?

scala - 为什么scala.util.Failure具有类型参数?

scala - 在 Scala 中提供类型类的实例时使用 vals 还是 object 更好

c - 将 fscanf 与动态分配的缓冲区一起使用

c# - 对象与 SetValue 和枚举的目标类型不匹配

c# - 如何在不同的 .aspx 文件或制作函数库中重用相同的函数?