我是MongoDB的新手,我正在尝试让C#驱动程序工作序列化F#类.我使用可变F#字段和无参数构造函数使用类自动化程序,但实际上我需要保留不变性,所以我开始考虑实现IBsonSerializer来执行自定义序列化.我没有找到任何关于编写其中一个的文档,所以我们只是试图从驱动程序源代码中推断出来.
我遇到了一个问题,当在序列化程序上调用Deserialize方法时,CurrentBsonType被设置为EndOfDocument而不是我期待的开始.我在C#中编写了等效文件,以确保它不是一些F#怪异,但问题仍然存在.序列化部分似乎工作正常,可以从shell查询.以下是示例代码:
class Calendar {
public string Id { get; private set; }
public DateTime[] Holidays { get; private set; }
public Calendar(string id, DateTime[] holidays) {
Id = id;
Holidays = holidays;
}
}
class CalendarSerializer : BsonBaseSerializer {
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) {
var calendar = (Calendar) value;
bsonWriter.WriteStartDocument();
bsonWriter.WriteString("_id", calendar.Id);
bsonWriter.WriteName("holidays");
var ser = new ArraySerializer<DateTime>();
ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null);
bsonWriter.WriteEndDocument();
}
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个使用CRTP按类型参数化的特性列表,并且无法弄清楚如何表达类型约束.以下是一些说明问题的示例代码:
trait A[X] {
def x: X
}
trait B[Y <: A[Y]] {
def y(i: Int): Y
}
case class C(i: Int) extends A[C] {
def x = C(i)
}
case class D(i: Int) extends A[D] {
def x = D(i)
}
case class E() extends B[C] {
def y(i: Int) = C(i)
}
case class F() extends B[D] {
def y(i: Int) = D(i)
}
object Program extends App {
def emptyList[X[_ <: Z forSome { type Z <: …Run Code Online (Sandbox Code Playgroud) 我试图使用一个有区别的联合的特定成员作为参数类型.例如:
type SomeUnion =
| A of int * int
| B of string
type SomeType(A(i, j)) =
member this.I = i
member this.J = j
let a = A(10, 20)
let instance = SomeType(a)
Run Code Online (Sandbox Code Playgroud)
但这是非法的语法,并抱怨SomeType的param列表中的"Unexpected symbol"('in type definition'.这是有效的语法:
let doSomethingWithA (A(i, j)) = i + j
Run Code Online (Sandbox Code Playgroud)
但类型签名SomeUnion -> int不是A -> int,而是抱怨模式匹配不完整(鉴于签名可以理解).
这可能吗?我相信F#union成员被编译为CLR类,所以理论上似乎可能,但实际上是这样(即不使用像反射这样的东西)?否则我想你必须做手动OOP方式,这更详细,不能保证完全匹配.