8

Non si tratta di moduli Windows, è solo per lo "sfondo".Upcast obbligatorio in caso di sovraccarico diverso

stavo giocherellando in giro Windows Form quando ho ottenuto un errore su un AddRange per un MenuStrip.Items che richiede di gettare ToolStripMenuItem in ToolStripItem

Ma ho già un AddRange per un Form.Controls prima che non richiedeva calchi.

Dopo un po 'di sperimentazione sono riuscito a trovare che l'errore si verifica quando ci sono di sovraccarico multiplo per quel AddRange Così ho cercato di convalidare il mio pensiero:

type Foo() = class end 
type Bar() = inherit Foo() 

type FooCollection() = class end // not really necessary 

type Test1() = 
    member __.AddRange (col: FooCollection) =() // could be an int or anything instead 
    member __.AddRange (foos: Foo []) =() 

type Test2() = member __.AddRange (foos: Foo []) =() 

let lst1, lst2 = Test1(), Test2() 
lst1.AddRange [|Bar()|] // error: have to explicitely cast => [|Bar() :> Foo|] 
lst2.AddRange [|Bar()|] // works 

La questione è semplicemente perché; dal mio punto di vista la chiamata non è ambiguo

+0

Per me la domanda è perché funziona in test2, se si rende il metodo statico smette di funzionare. – Gustavo

+0

Test2 funziona per me con metodo statico (Test1 continua a non funzionare ovviamente) – Sehnsucht

+0

Impossibile modificare il precedente qui è un esempio di [ideone] (http://ideone.com/KLGwRb) per il test statico – Sehnsucht

risposta

2

Dopo aver letto la 14.4.3 F# spec (suggerito da Gustavo, complimenti a lui)

Il # compilatore F determina se inserire la flessibilità dopo l'istanza esplicita, ma prima di qualsiasi argomenti sono controllati

Capisco che la flessibilità non viene mai inserita per un metodo che ha sovraccarichi perché richiederebbe il controllo degli argomenti da scegliere.

+0

Non penso che la flessibilità sia coinvolta; la questione non è se puoi passare un 'Bar []' a una funzione che aspetta un 'Foo []' (non puoi - provarlo con un non-letterale), è se trattare il letterale stesso come un'istanza di 'Bar []' o 'Foo []'. – kvb

+0

Dalla mia comprensione (limitata): Quando si ha un valore non letterale, il tipo è già "congelato", quindi è quello giusto o no. fine della storia. Quando si ha un non letterale il tipo non è "congelato" (per non dire flessibile) dipende dal contesto. Per un singolo metodo il contesto è chiaro, quindi "si tenta di conformare il tipo di parametro al tipo di argomento" (il mio modo di descriverlo). Per un metodo sovraccarico il contesto non è così chiaro, quindi il compilatore non si preoccupa di provare a provare che deve essere lo sviluppatore per renderlo più chiaro. – Sehnsucht

+0

Sì, penso che sia fondamentalmente giusto - ma non è quello che è l'inserimento della flessibilità menzionato in 14.4.3. Invece, si tratta rigorosamente di accettare argomenti di tipi che sono noti staticamente come sottotipi dei tipi di argomenti del metodo, che non si applica in questo caso. – kvb

Problemi correlati