Question

Y at-il de mal à utiliser un opérateur implicite comme suit:

//linqpad c# program example
void Main()
{
    var testObject = new MyClass<int>() { Value = 1 };

    var add = 10 + testObject; //implicit conversion to int here
    add.Dump(); // 11
}

class MyClass<T>
{
    public T Value { get; set; }
    public static implicit operator T (MyClass<T> myClassToConvert)
    {
        return myClassToConvert.Value;
    }
}

Je pensais que je pouvais traiter comme exemple de l'objet comme une valeur de type de cette façon, mais en voyant comme je l'ai jamais vu un exemple de ce que je pensais que peut-être il y avait une raison pas à faire quelque chose comme ce que quelqu'un pourrait signaler?

Dans mon code actuel, je pensais à le faire dans le cadre d'une couche d'abstraction de données, afin que je puisse retourner des objets avec des informations décrivant les données sous-jacentes, mais elles permettent au code logique de la traiter comme un type de valeur quand tout ce qu'il faut à savoir est la valeur au sujet, et en même temps garder tout agréable et le type en sécurité avec les génériques.

Était-ce utile?

La solution

Si toutes les conditions suivantes sont remplies:

  • tous valeurs possibles de votre type de MyClass<T> (y compris null si ce n'est pas un type de valeur!) La carte à une valeur valide de T

  • l'opérateur implicite ne lève jamais (même pas pour null!)

  • la conversion implicite est logique sémantique et n'est pas source de confusion pour le programmeur client

alors il n'y a rien de mal à ce. Bien sûr, vous peut faire l'une de ces trois choses, mais ce serait une mauvaise conception. En particulier, un opérateur implicite qui jette peut être très difficile à déboguer parce que l'endroit où on l'appelle ne dit pas qu'il est appelé.

Par exemple, considérons que T? n'a pas de conversion implicite à T (où T est, bien sûr, un type de valeur). S'il y avait un tel opérateur implicite, il faudrait jeter lorsque la T? est nulle, car il n'y a pas de valeur évidente pour convertir null à ce serait logique pour une valeur de type T.


Permettez-moi de donner un exemple où j'ai eu du mal à le débogage d'un problème où l'opérateur implicite jeté:

public string Foo()
{
    return some_condition ? GetSomething() : null;
}

Ici, GetSomething retourne quelque chose d'un type que j'ai écrit qui a une conversion implicite définie par l'utilisateur à string. J'ai fait absolument sûr que GetSomething ne pourrait jamais revenir null, et pourtant je suis un NullReferenceException! Pourquoi? Parce que le code ci-dessus est pas équivalent à

return some_condition ? (string)GetSomething() : (string)null;

mais

return (string)(some_condition ? GetSomething() : (Something)null);

Maintenant, vous pouvez voir où le null vient!

Autres conseils

C'est un grand modèle. Il suffit de garder à l'esprit que pour l'utiliser comme une variable de type T, vous devez soit explicitement jeter à T, ou l'assigner à une variable de type T. Le casting aura lieu automatiquement les appels de méthode et d'autres choses (comme votre exemple d'addition) qui prennent T.

conversion implicite sans affectation?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top