Puis-je append une conversion implicite pour deux classes que je ne contrôle pas directement?

Je voudrais pouvoir implicitement convertir entre deux classes qui sont par ailleurs incompatibles.

Une de ces classes est Microsoft.Xna.Framework.Vector3 , et l’autre est simplement une classe Vector utilisée dans un projet F #. J’écris un jeu 3D en C # avec XNA et, bien que dessiné en 3D, le gameplay ne se déroule que dans deux dimensions (c’est une vue à vol d’oiseau). La classe F # s’occupe de la physique, en utilisant un vecteur 2D:

 type Vector SuperUnit> = | Cartesian of 't * 't | Polar of 't * float member this.magnitude = match this with | Cartesian(x, y) -> x.newValue(sqrt (x.units ** 2.0 + y.units ** 2.0)) | Polar(m, _) -> m.newValue(m.units) member this.direction = match this with | Cartesian(x, y) -> tan(y.units / x.units) | Polar(_, d) -> d member this.x = match this with | Cartesian(x, _) -> x | Polar(m, d) -> m.newValue(m.units * cos(d)) member this.y = match this with | Cartesian(_, y) -> y | Polar(m, d) -> m.newValue(m.units * sin(d)) 

Cette classe de vecteurs utilise le système d’unités utilisé par le projet de physique, qui prend des unités de mesure F # natives et les regroupe (unités de distance, de temps, de masse, etc.).

Mais XNA utilise sa propre classe Vector3 . Je souhaite append une conversion implicite du Vector F # au XNA Vector3 qui Vector3 deux dimensions de la jouabilité, l’axe “haut”, etc. Ce serait simple, mais simplement Vector v -> new Vector3(vx, vy, 0) ou quelque chose.

Je n’arrive pas à comprendre comment le faire. Je ne peux pas append de conversion implicite dans F # car le système de types ne le permet pas (à juste titre). Je ne peux pas l’append à la classe Vector3 car cela fait partie de la bibliothèque XNA. Autant que je sache, je ne peux pas utiliser une méthode d’extension:

 class CsToFs { public static implicit operator Vector3(this Vector v) { //... } } 

Est une erreur sur le mot this clé this , et

 class CsToFs { public static implicit operator Vector3(Vector v) { return new Vector3((float)vxunits, (float)vyunits, 0); } public static void test() { var v = Vector.NewCartesian(Distance.Meters(0), Distance.Meters(0)); Vector3 a; a = v; } } 

est une erreur sur a = v; (impossible de convertir implicitement …).

Y a-t-il un moyen de faire cela sans pouvoir placer le casting dans aucune des classes? En dernier recours, je pouvais open Microsoft.Xna.Framework et effectuer la conversion en f #, mais cela me semble faux: la bibliothèque de physique ne devrait pas savoir ni se soucier du cadre que j’utilise pour écrire le jeu.

    Non, tu ne peux pas. L’opérateur implicite doit être défini en tant que membre d’une des classes. Cependant, vous pouvez définir une méthode d’extension (votre exemple ne fonctionnait pas car les méthodes d’extension devaient appartenir à une public static class ).

     public static class ConverterExtensions { public static Vector ToVector (this Vector3 input) { //convert } } 

    En C #, vous ne pouvez pas. Vous pouvez fournir des types de descendance avec les conversions supplémentaires (à condition que les types ne soient pas scellés); Vous pouvez également fournir une classe wrapper générique qui ajoute en quelque sorte la conversion.

    La commodité de tout cela dépend de la manière dont ces wrappers / adaptations peuvent être utilisés avec les API d’origine.

    Sur une autre note, je vois que vous utilisez également F #. IIRC F # est supposé avoir un certain niveau de capacité de méta-programmation (comme de nombreux langages fonctionnels pour .NET, tels que Boo et Nemerle). Cela ne me surprendrait pas si cela pouvait être utilisé ici. Malheureusement, mon F n’est pas assez fort pour aider là-bas