I'd like to be able to implicitly convert between two classes which are otherwise incompatible.
One of the classes is Microsoft.Xna.Framework.Vector3
, and the other is just a Vector
class used in an F# project. I'm writing a 3d game in C# with XNA, and -- although it's drawn in 3D, the gameplay takes place in only two dimensions (it's a birds-eye-view). The F# class takes care of the physics, using a 2D vector:
type Vector<'t when 't :> SuperUnit<'t>> =
| 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))
This vector class makes use of the unit system used by the physics project, which takes native F# units of measure and groups them together (units of Distance, Time, Mass, etc).
But XNA uses its own Vector3
class. I want to add an implicit conversion from the F# Vector
to the XNA Vector3
which takes care of which two dimensions the gameplay takes place in, which axis is "up", etc. It'd be simple, just Vector v -> new Vector3(v.x, v.y, 0)
or something.
I can't figure out how to do it though. I can't add an implicit conversion in F# because the type system (rightly) doesn't allow it. I can't add it to the Vector3 class because that is part of the XNA library. As far as I can tell I can't use an extension method:
class CsToFs
{
public static implicit operator Vector3(this Vector<Distance> v)
{
//...
}
}
Is an error on the this
keyword, and
class CsToFs
{
public static implicit operator Vector3(Vector<Distance> v)
{
return new Vector3((float)v.x.units, (float)v.y.units, 0);
}
public static void test()
{
var v = Vector<Distance>.NewCartesian(Distance.Meters(0), Distance.Meters(0));
Vector3 a;
a = v;
}
}
is an error on a = v;
(cannot implicitly convert...).
Is there a way to do this without being able to put the cast in either of the classes? As a last resort I could open Microsoft.Xna.Framework
and do the conversion in F#, but that seems wrong to me -- the physics library shouldn't know or care what framework I'm using to write the game.
The Implicit Operator According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to your C# class, which can accepts any reasonably convertible data type without type casting.
Type Conversion in C++ There are two types of type conversion: Implicit Type Conversion Also known as 'automatic type conversion'. Done by the compiler on its own, without any external trigger from the user. Generally takes place when in an expression more than one data type is present.
You can implicitly convert from an expression of type dynamic to any other type. What this means is that the compiler allows an implicit conversion (no cast operator) from the dynamic type to any other type and compilation succeeds.
An implicit type conversion is one that is done by the runtime automatically. You don't need to cast to any specific type.
No, you can't. The implicit operator has to be defined as a member of one of the classes. However, you can define an extension method (your example didn't work as extension methods have to be in a public static class
).
public static class ConverterExtensions
{
public static Vector ToVector (this Vector3 input)
{
//convert
}
}
In C# you cannot. You could provide descendant types that have the extra conversions (provided the types aren't sealed); Or you could provide a generic wrapper class that somehow adds the conversion.
The convenience of all this depends on the way in which these wrappers/adaptations can be used with the original APIs.
On another note I see you are useing F# as well. IIRC F# is supposed to have some level of meta-programming ability (like many functional languages for .NET, such as Boo and Nemerle). It would not surprise me if that could be used here. Unfortunately my F is not sharp enough to help there
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With