2014-05-12 20 views
6

Nell'esempio seguente, ho due vincoli, Foobar e IFoobar<T>, su tipo T in classe generica FoobarList<T>. Ma il compilatore dà un errore: non è possibile convertire implicitamente il tipo "Foobar" in "T". Esiste una conversione esplicita (che le manca un cast?)Priorità di più vincoli su un parametro di tipo generico

interface IFoobar<T> 
{ 
    T CreateFoobar(); 
} 

class Foobar : IFoobar<Foobar> 
{ 
    //some foobar stuffs 
    public Foobar CreateFoobar() { return new Foobar(); } 
} 

class FoobarList<T> where T : Foobar, IFoobar<T> 
{ 
    void Test(T rFoobar) 
    { 
     T foobar = rFoobar.CreateFoobar(); //error: cannot convert Foobar to T 
    } 
} 

Sembra che il compilatore considera CreateFoobar come un metodo in Foobar, ma non quello di IFoobar. Posso risolvere la compilazione dividendo Foobar in un FoobarBase classe base, e che attua l'IFoobar interfaccia nella sua classe derivata, come segue:

interface IFoobar<T> 
{ 
    T CreateFoobar(); 
} 

abstract class FoobarBase 
{ 
    //some foobar stuffs 
} 

class Foobar : FoobarBase, IFoobar<Foobar> 
{ 
    public Foobar CreateFoobar() { return new Foobar(); } 
} 

class FoobarList<T> where T : FoobarBase, IFoobar<T> 
{ 
    void Test(T rFoobar) 
    { 
     T foobar = rFoobar.CreateFoobar(); 
    } 
} 

È ingombrante dividere Foobar in due classi. C'è un modo migliore per risolvere questo problema?

+1

L'implementazione dell'interfaccia è di aiuto esplicito? – Rotem

risposta

4

appena lanciato rFoobar a IFoobar<T>:

T foobar = ((IFoobar<T>)rFoobar).CreateFoobar(); 

In questo modo si sta chiamando un metodo che restituisce T piuttosto che solo Foobar.

Come suggerisce Rotem, cambiando il metodo di Foobar usare implementazione dell'interfaccia esplicita lavora troppo:

Foobar IFoobar<Foobar>.CreateFoobar() { return new Foobar(); } 

questo modo che il metodo non si troverà in T, così ancora una volta si risolverà per il metodo di interfaccia.