Frage

Es gibt eine Mikrofrage, hier, warum in der endgültigen Antwort, die ich mir ausgedacht habe (ganz unten), ein Upcast benötigt wird. Und eine Makrofrage, ob ich nur den "Elefanten im Raum" vermisse: Eine wirklich offensichtliche, prägnante Art, das zu tun, was ich will [bitte fragen Sie mich nicht - warum ich will, was ich will; Nehmen Sie es einfach als gegeben, dass ich das will, und es ist ...

Ich möchte ein BSondocument von F# über den MongoDB.bson CLR Assmbly initialisieren. Die besondere Überladung des BSondocument -Konstruktors, von der ich denke, dass sie verwenden sollte, ist

MongoDB.Bson.BsonDocument.BsonDocument(IDictionary<string,object>)

Und hier ist der Grund, warum ich denke, dass dies derjenige ist, den ich verwenden sollte (Folgendes ist ein langer Spaziergang durch den Garten der Typen ...)

Die C# -Probe von der MongoDB -Site MongoDB CSHARP -Fahrer -Tutorial Verwendet die Sammlungsinitializer-Syntax, die einen oder mehrere Aufrufe von .ADD auf der von BSondocument entlarvten Schnittstelle ordnet. Das Tutorial -Beispiel ähnelt wie folgt:

var bdoc = new BsonDocument { { "a", "1" }, { "b", "2" }, };

Ich bin nicht sicher, welche Überlastung von .Add verwendet wird (und weiß nicht, wie man Visual Studio einchecku003Cstring, object> . In diesem Fall werden die zweiten Werte in jedem Paar, nämlich "1" und "2", der Typ -Zeichenfolge automatisch (durch Vererbung) auch vom Typ Objekt, so dass alles in Ordnung ist. Und die anderen Überladungen von .ADD, bei denen das zweite Element vom Typ bsonValue ist, was ein abstrakter Supertyp des BSONSPRING ist, der eine implizite Konvertierung von .NET String aufweist, unabhängig davon, welche Überlastung verwendet wird. Also ist auch dort auch alles in Ordnung. Es spielt keine Rolle, welche Überlastung des Konstruktors aufgerufen wird.

Dies ist ein wenig schwierig, um in ein F# Äquivalent zu manövrieren, da es schwierig ist, die .ADD -Methode des BSondocuments zu erreichen. ich dachte an

[("a", "1");("b", "2");] |> Seq.iter BsonDocument.Add

Das funktioniert jedoch nicht, weil bSondocument.add keine statische Methode ist. Ich könnte das BSondocument instanziieren und dann eine lustige Lambda schreiben, die die BSondocument -Methode des BSonDocument nennt, die zumindest die Veränderbarkeit des Spaßes isoliert würde:

[("a", "1");("b", "2");] |> Seq.fold ...

Dies stellt sich jedoch als super hässlich heraus, beide aufgrund des Spaßes, der eine explizite Typnotation auf dem BSondocument benötigt, da die Variable, die sich auf das BSondocument bezieht Haben Sie (noch) genügend Informationen, und weil der Spaß (zumindest anscheinend anscheinend) keine Möglichkeit hat, zu wissen, dass er für den zweiten Wert in jedem Paar auf die implizite Konvertierung von String zu BSonstring zugreifen sollte ...

let bdoc = [("a","1");("b","2");] |> Seq.fold (fun (doc:BsonDocument) pair -> doc.Add(fst pair, new BsonString(snd pair))) (new BsonDocument())

... Egal, ich dachte, ich werde die größere Überladung des Konstruktors verwenden

BsonDocument(IDictionary<string, object>)

Dies ist jedoch folgendermaßen gezwungen:

let bdoc = (new BsonDocument(dict
  [("a", "1" :> Object); 
   ("b", "2" :> Object);
  ]))

Wenn ich die Upcasts herausnehme

:> Object

Dann beschwert sich F#, dass es keine Überladung BSondocument finden kann.

(Langer Spaziergang im Garten ist vorbei ...)

Nach all dem ist die Micro -Frage, warum in F#nicht herausfinden kann, dass die "1" und "2" im Eingabewörterbuch Objekte sind und somit die entsprechende Überladung finden?

Und die Makro-Frage mit größerem Bild ist, ob ich gerade die entsprechenden, bestpraktischen, supercoolen und prägnanten Möglichkeiten verpasst habe, dies in F# zu tun?

War es hilfreich?

Lösung

Dies ist kein MongoDB -Problem. Das Problem ist das ("1", "2") ist ein string * string, Sie erstellen also eine IDictionary<string,string> mit Ihrer dict Konstrukteur. F# hat die Typen abgeleitet, die Sie angegeben haben. Der Typ -Inferenz wird nicht bestimmen, dass Sie gemeint haben obj in diesem Fall. Deshalb muss man es sagen.

> dict
  [("a", "1" :> obj); 
   ("b", "2" :> obj);
  ];;
val it : System.Collections.Generic.IDictionary<string,obj> =
  seq [[a, 1] {Key = "a";
               Value = "1";}; [b, 2] {Key = "b";
                                      Value = "2";}]
> dict
  [("a", "1"); 
   ("b", "2");
  ];;
val it : System.Collections.Generic.IDictionary<string,string> =
  seq [[a, 1] {Key = "a";
               Value = "1";}; [b, 2] {Key = "b";
                                      Value = "2";}]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top