Introduction
I am aware that \"user-defined conversions to or from a base class are not allowed\". MSDN gives, as an explanation to this rule, \"You
It seems the reference equality was not your concern, then you can say:
Code
public class Entity {
public sealed class To where U : Entity {
public static implicit operator To(Entity entity) {
return new To { m_handle=entity.Pointer };
}
public static implicit operator U(To x) {
return (U)Activator.CreateInstance(typeof(U), x.m_handle);
}
To() { // not exposed
}
IntPtr m_handle; // not exposed
}
IntPtr Pointer; // not exposed
public Entity(IntPtr pointer) {
this.Pointer=pointer;
}
}
public class Body:Entity {
public Body(IntPtr pointer) : base(pointer) {
}
}
// added for the extra demonstration
public class Context:Body {
public Context(IntPtr pointer) : base(pointer) {
}
}
and the
Test
public static class TestClass {
public static void TestMethod() {
Entity entity = new Entity((IntPtr)0x1234);
Body body = (Entity.To)entity;
Context context = (Body.To)body;
}
}
You didn't write the accessors but I took the encapsulation into account, to not expose their pointers. Under the hood of this implementation is use an intermediate class which is not in the inheritance chain but chain the conversion.
Activator involved here is good for not adding extra new() constraint as U are already constrained to Entity and have a parameterized constructor. To though is exposed but sealed without exposing its constructor, it can only be instantiated from the conversion operator.
In the test code, the entity actually converted to a generic To object and then the target type, so is the extra demonstration from body to context. Because To is a nested class, it can access the private Pointer of the containing class, thus we can accomplish things without exposing the pointer.
Well, that's it.