Introduction
Je suis conscient que "les conversions définies par l'utilisateur vers ou depuis une classe de base ne sont pas autorisées". MSDN donne, comme explication à cette règle, "Vous n'avez pas besoin de cet opérateur".
Je comprends qu'une conversion définie par l'utilisateur à une classe de base n'est pas nécessaire, car cela est évidemment fait implicitement. Cependant, j'ai besoin d'une conversion de une classe de base.
Dans ma conception actuelle, une enveloppe de code non géré, j'utilise un pointeur, stocké dans une classe Entity. Toutes les classes utilisant un pointeur dérivent de cette classe Entity, par exemple, une classe Body.
J'ai donc :
Méthode A
class Entity
{
IntPtr Pointer;
Entity(IntPtr pointer)
{
this.Pointer = pointer;
}
}
class Body : Entity
{
Body(IntPtr pointer) : base(pointer) { }
explicit operator Body(Entity e)
{
return new Body(e.Pointer);
}
}
Cette distribution est la plus illégale. (Notez que je n'ai pas pris la peine d'écrire les accesseurs). Sans lui, le compilateur sera me permettre de le faire :
Méthode B
(Body)myEntity
...
Cependant, au moment de l'exécution, j'obtiendrai une exception indiquant que cette distribution est impossible.
Conclusion
Par conséquent, j'ai besoin d'une conversion définie par l'utilisateur. de une classe de base, et C# me le refuse. En utilisant la méthode A, le compilateur se plaindra mais le code fonctionnera logiquement à l'exécution. En utilisant la méthode B, le compilateur ne se plaindra pas mais le code échouera évidemment à l'exécution.
Ce que je trouve étrange dans cette situation, c'est que MSDN me dit que je n'ai pas besoin de cet opérateur, et que le compilateur agit comme suit comme si c'était possible implicitement (méthode B). Que dois-je faire ?
Je suis conscient que je peux utiliser :
Solution A
class Body : Entity
{
Body(IntPtr pointer) : base(pointer) { }
static Body FromEntity(Entity e)
{
return new Body(e.Pointer);
}
}
Solution B
class Body : Entity
{
Body(IntPtr pointer) : base(pointer) { }
Body(Entity e) : base(e.Pointer) { }
}
Solution C
class Entity
{
IntPtr Pointer;
Entity(IntPtr pointer)
{
this.Pointer = pointer;
}
Body ToBody()
{
return new Body(this.Pointer);
}
}
Mais honnêtement, toutes les syntaxes pour ceux-ci sont horribles et devraient en fait être des casts. Donc, un moyen de faire fonctionner les casts ? Est-ce un défaut de conception du C# ou ai-je manqué une possibilité ? C'est comme si C# ne me faisait pas assez confiance pour écrire ma propre conversion base-enfant en utilisant leur système de cast.