La relativa sezione delle specifiche C# è
La sezione è lunga, ma distilla a questo: si sta definendo una conversione esplicita con (Foo)doub
, e dal momento che stai usando una conversione esplicita il compilatore sceglierà le conversioni disponibili più specifiche, incluse le conversioni che sono solo esplicite, per fare i passaggi intermedi lungo la conversione percorso (se disponibili).
Se U contiene esattamente un operatore di conversione definito dall'utente che converte da SX a TX, allora questo è il più specifica conversione operatore. Se non esiste alcun operatore di questo tipo o se esiste più di uno di questi operatori , la conversione è ambigua e si verifica un errore in fase di compilazione. In caso contrario, viene applicata la conversione definita dall'utente:
Se S non è SX, viene eseguita una conversione esplicita standard da S a SX.
L'operatore di conversione definito dall'utente più specifico è invocato per la conversione da SX a TX.
Se TX non è T, viene eseguita una conversione esplicita standard da TX a T.
(sottolineatura mia)
Qui S
è il tipo di origine e T
è il tipo di destinazione, mentre SX
è il tipo fonte più specifico definito nelle operatori espliciti del tipo di destinazione (ie; Foo
) e TX
è il tipo di destinazione più specifico definito negli operatori espliciti di T
.
Qui una conversione esplicita esiste da double
a int
ed è quindi scelto come il più appropriato per convertire dal tipo di argomento sorgente (double -- S
) per il tipo argomento di input dell'operatore esplicito (int -- SX
). Non è necessario che sia esplicito poiché sei già stato esplicito sulla conversione in Foo
.
Questo funziona solo perché non ci sono alternative ambigue. Se è stato definito Foo
avere:
struct Foo
{
public int value;
public uint uvalue;
public static explicit operator Foo(int val)
{
return new Foo { value = val };
}
public static explicit operator Foo(uint val)
{
return new Foo { uvalue = val };
}
}
per esempio, questo produce un errore di compilazione (con lo stesso Main
) di:
errore Foo 1 ambigui definiti dall'utente conversioni.operatore esplicito Foo (uint)' e 'operatore Foo.explicit Foo (int)' durante la conversione da 'doppio' a 'Foo'
Ancora una volta, questo è il libro (per il primo comma citato), in quanto l'insieme di conversioni disponibili U
contiene ora due conversioni esplicite ugualmente valide e il compilatore non può decidere se intendi richiamare la conversione int
o la conversione uint
. Nell'esempio iniziale c'è solo una volta la scelta, ed è chiaro, così il compilatore lo prende.
questo è esplicito. se provi "operatore implicito Foo (int val)' vedrai che non puoi scrivere 'Foo foo = doub;' ... –
@ M.kazemAkhgary Questo codice sta causando un errore. http://ideone.com/ttBLLX Ma con 'operatore pubblico statico implicito Foo (int val)' 'Foo a = (Foo) dubbio;' funziona – Alex78191
Le risposte date sono buone. Per ulteriori informazioni, vedere https://blogs.msdn.microsoft.com/ericlippert/2007/04/16/chained-user-defined-explicit-conversions-in-c/ e https://blogs.msdn.microsoft.com/ericlippert/2007/04/18/chained-user-defined-explicit-conversions-in-c-part-two/e https://blogs.msdn.microsoft.com/ericlippert/2007/04/20/chained- conversioni esplicite definite dall'utente-in-c-part-three/ –