2015-02-05 14 views
9

Diciamo che ho un seguente interfaccia C#:Perché una classe generica che implementa un'interfaccia generica con vincoli di tipo deve ripetere questi vincoli?

public interface IInterface<T> where T : SomeClass 
{ 
    void InterfaceMethod(); 
} 

E SomeClass è definito come segue:

public class SomeClass 
{ 
    public void SomeMethod(); 
} 

Ora vorrei definire l'implementazione dell'interfaccia, che non verrà compilato :

public class InterfaceImpl<T> : IInterface<T> 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Gives Error 
    } 
} 

prima che cambi a:

public class InterfaceImpl<T> : IInterface<T> where T : SomeClass 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Compiles fine 
    } 
} 

Non avrebbe senso che i vincoli di tipo siano anche "ereditati" (non la parola giusta, lo so) dall'interfaccia?

+1

Probabilmente avrebbero potuto essere realizzati "di default", se non è stato specificato nulla. Ma la sintassi attuale consente di ridefinire i vincoli (ereditarietà, nuova() parola chiave, ecc.) Che va bene. – AFract

risposta

9

La classe non ha bisogno di ripetere questi vincoli, è necessario fornire un tipo che soddisfi i limiti dell'interfaccia. Ci sono diversi modi di farlo:

  • può fornire un tipo specifico che soddisfa i vincoli, o
  • E 'possibile inserire i propri vincoli su un tipo generico che sono forte di quello che l'interfaccia si aspetta, oppure
  • Può ripetere i vincoli dall'interfaccia.

La cosa fondamentale è che T in InterfaceImpl<T> appartiene InterfaceImpl, in modo da qualunque vincoli che sono immessi sul T deve essere InterfaceImpl 's proprio.

+0

Spiegazione molto bella e chiara, l'ultima frase è stata cruciale per me :) Conoscendo la tua risposta, l'unica cosa che non capisco è perché C# mi permetterà di creare una classe che non faccia nessuna delle cose menzionate nel tuo risposta? Supponiamo, si tratta di una classe astratta che non chiama i metodi di T - Posso compilarla senza porre alcun vincolo su T o specificando il tipo, che soddisferebbe i vincoli dell'interfaccia. –

+1

@BartekEborn Non sono sicuro di cosa intendi. In situazioni in cui un'interfaccia generica ha un vincolo, una classe che la implementa deve fornire un parametro compatibile, indipendentemente dal fatto che la classe di implementazione sia astratta o meno ([demo - non compila] (http://ideone.com/WG9pR1)). Sono sicuro che intendevi qualcos'altro. Potresti fare una demo che mostri cosa intendi? Puoi fare clic su "fork" sul mio demo e modificarlo se preferisci. – dasblinkenlight

+0

Questo è esattamente ciò che intendevo. Mio male, mi dispiace per il tuo impegno. Mi sono fidato di Intellisense che non ha evidenziato l'errore in questo caso (sebbene lo sia stato in precedenza). Dopo averlo provato, mi vergogno :(Scusa ancora una volta! –

Problemi correlati