Domanda

C'è male niente con l'utilizzo di un operatore implicita come la seguente:

//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;
    }
}

stavo pensando che potrei trattare come istanza dell'oggetto come valore tipo in questo modo, ma visto che non ho mai visto un esempio di questo ho pensato che forse c'era un motivo non da fare qualcosa di simile che qualcuno potrebbe indicare?

Nel mio codice vero e stavo pensando di fare questo come parte di un livello di astrazione dati, in modo da poter restituire gli oggetti con le informazioni che descrivono i dati sottostanti, ma permettere al codice della logica di trattarlo come un tipo di valore, quando tutto ciò che serve di conoscere è il valore, e allo stesso tempo tenere tutto bello e il tipo sicuro con i farmaci generici.

È stato utile?

Soluzione

Se tutte le seguenti condizioni:

  • tutti possibili valori del vostro tipo MyClass<T> (tra cui null se non è un tipo di valore!) Mappare un valore valido di T

  • l'operatore implicita mai getta (neanche per null!)

  • la conversione implicita ha senso semantico e non è fonte di confusione per il programmatore client

allora non c'è niente di sbagliato in questo. Naturalmente si potrebbe fare nessuna di queste tre cose, ma sarebbe cattivo design. In particolare, un operatore implicito che getta può essere molto difficile da eseguire il debug perché il luogo dove è chiamato non dice che si riceve una chiamata.

Ad esempio, si consideri che T? ha alcuna conversione implicita a T (dove T è, naturalmente, un tipo di valore). Se ci fosse un operatore come implicita, avrebbe dovuto gettare quando il T? è nullo, in quanto non v'è alcun valore ovvio per convertire null a che avrebbe senso per qualsiasi valore del tipo T.


Vi faccio un esempio in cui ho avuto problemi di debug un problema in cui l'operatore implicita buttato:

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

Qui, GetSomething restituito qualcosa di un tipo che ho scritto che ha una conversione implicita definito dall'utente a string. Ho fatto assolutamente sicuri che GetSomething non potrebbe mai tornare null, e tuttavia ho ottenuto un NullReferenceException! Perché? Poiché il codice di cui sopra è non equivalente a

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

ma per

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

Ora si può vedere dove la null è venuto da!

Altri suggerimenti

Questo è un grande modello. Basta tenere a mente che, al fine di utilizzarlo come una variabile di tipo T, si deve lanciare in modo esplicito a T, oppure assegnarlo a una variabile di tipo T. Il cast avrà automaticamente posto in chiamate di metodo e altre cose (come ad esempio il vostro esempio oltre) che accettano un T.

conversione implicita senza assegnazione?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top