En C #, nous pouvons surcharger l'opérateur de conversion implicite comme ceci (exemple de MSDN ):
struct Digit
{
/* ... */
public static implicit operator byte(Digit d) // implicit digit to byte conversion operator
{
/* ... */
}
}
Ainsi, nous pouvons avoir un type, un type de valeur personnalisé , se convertissant comme par magie en un autre type (non lié), laissant le public perplexe (jusqu'à ce qu'ils regardent dans les coulisses et voient l'opérateur de conversion implicite, c'est-à-dire).
Je n'aime pas laisser quiconque lit mon code avec perplexité. Je ne pense pas que beaucoup de gens le fassent.
La question est, quels sont les cas d'utilisation de l'opérateur de conversion de type implicite qui ne rendront pas mon code beaucoup plus difficile à comprendre?
Réponses:
Je ne recommanderais que des conversions implicites entre des types qui représentent à peu près les mêmes valeurs de différentes manières. Par exemple:
RGB
,HSL
,HSV
etCMYK
.Meter
vsInch
).Cependant, il existe des directives strictes qui indiquent quand il n'est pas approprié de définir une conversion implicite:
InvalidCast
exception ( ), elle ne devrait pas être implicite.O(1)
opération, elle ne devrait pas être implicite.Supposons maintenant que votre opérateur de conversion
f: T1 -> T2
ne viole aucune des règles ci-dessus, alors le comportement suivant indique fortement que la conversion peut être implicite:a == b
alorsf(a) == f(b)
.a != b
alorsf(a) != f(b)
.a.ToString() == b.ToString()
alorsf(a).ToString() == f(b).ToString()
.T1
etT2
.la source
T1
(impliquées par la==
relation onT1
) sont toujours mappées à deux valeurs dans la même classe d'équivalence deT2
. Maintenant que j'y pense, je suppose que la première propriété devrait être requise pour une conversion implicite.Lorsque les types ne sont pas indépendants (des programmeurs). Il existe de (rares) scénarios où vous avez deux types non liés (en ce qui concerne le code), qui sont réellement liés (en ce qui concerne le domaine ou les programmeurs raisonnables).
Par exemple, du code pour effectuer une correspondance de chaîne. Un scénario courant consiste à faire correspondre un littéral de chaîne. Plutôt que d'appeler
IsMatch(input, new Literal("some string"))
, une conversion implicite vous permet de vous débarrasser de cette cérémonie - le bruit dans le code - et de vous concentrer sur le littéral de la chaîne.La plupart des programmeurs verront
IsMatch(input, "some string")
et comprendront rapidement ce qui se passe. Cela rend votre code plus clair sur le site de l'appel. En bref, cela permet de comprendre un peu plus facilement ce qui se passe, au détriment de la façon dont cela se passe.Maintenant, vous pourriez dire qu'une simple surcharge de fonction pour faire la même chose serait mieux. Et c'est. Mais si ce genre de chose est omniprésent, alors avoir une conversion est plus propre (moins de code, une cohérence accrue) que de faire une pile de surcharges de fonctions.
Et vous pourriez dire qu'il vaut mieux exiger des programmeurs qu'ils créent explicitement le type intermédiaire pour qu'ils voient "ce qui se passe réellement". C'est moins simple. Personnellement, je pense que l'exemple de correspondance de chaîne littérale est très clair sur "ce qui se passe vraiment" - le programmeur n'a pas besoin de connaître la mécanique de la façon dont tout se passe. Savez-vous comment tout votre code est exécuté par les différents processeurs sur lesquels votre code s'exécute? Il y a toujours une ligne d'abstraction où les programmeurs cessent de se soucier du fonctionnement de quelque chose. Si vous pensez que les étapes de conversion implicite sont importantes, n'utilisez pas la conversion implicite. Si vous pensez que c'est juste une cérémonie pour garder l'ordinateur heureux, et que le programmeur ferait mieux de ne pas voir ce bruit partout,
la source