2011-10-18 16 views
10

Ecco quello che sto cercando di fare, non sono nemmeno sicuro se possibile ..Specificare classe di farmaci generici dove T dovrebbe essere sottoclasse di altro tipo

sto creando BaseViewModel<T> e voglio che ad accettare tipi ereditato da Entity

Considerate questo codice:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware 
{ 

public T MyEntity; 

public SomeMethod() 
{ 
MyEntity.SomeEntityProperty = SomeValue; 
} 

} 

quindi, voglio dire che il mio T ereditato da Entity e quindi so che avrà SomeEntityProperty.

È possibile?

risposta

18

di Salvatore è del tutto corretto, volevo solo descrivere il concetto un po 'meglio.

Quello che ti serve è un "vincolo di tipo generico"; per specificare che il tipo usato come T deve conformarsi a certi comportamenti (come essere derivati ​​da un oggetto o un'interfaccia più derivati ​​di Object), aumentando così ciò che ti è permesso fare con quell'oggetto senza ulteriori casting (che è generalmente da evitare in generici).

Come dimostra la risposta di Salvatore, CG vengono definite utilizzando il "dove" parola chiave:

public abstract class BaseViewModel<T> : 
    NotificationObject, 
    INavigationAware 

    where T : Entity; 
{ 
    ... 

Questo GTC in sostanza stabilisce che ogni T deve derivare (per quanto a distanza) da Entità. Ciò consente di trattare T come se fosse un'entità (eccetto per l'istanziazione di nuovi Ts, che richiede un GTC aggiuntivo), indipendentemente da quanto più o meno derivato il tipo di parametro generico effettivo proviene dall'entità. È possibile chiamare qualsiasi metodo visualizzato su Entity e ottenere/impostare qualsiasi campo o proprietà.

Si può anche specificare che:

  • Il tipo deve essere una classe (where T:class), o in alternativa deve essere un ValueType (where T:struct). Ciò consente o impedisce il confronto e l'assegnazione di un'istanza T a null, che consente anche o impedisce l'utilizzo dell'operatore con coalizione nulla ??.
  • Il tipo deve avere un costruttore di una particolare firma (where T:new(), where T:new(int,float)). Ciò consente di creare istanze di Ts utilizzando la parola chiave new, assicurando in fase di compilazione che tutti i tipi utilizzati come Ts abbiano un costruttore con la firma prevista.
11
public abstract class BaseViewModel<T> : 
    NotificationObject, 
    INavigationAware 

    where T : Entity 
{ 

    public T MyEntity; 

    public SomeMethod() 
    { 
     MyEntity.SomeEntityProperty = SomeValue; 
    } 

} 
5

Basta usare la parola chiave where:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware 
    where T:Entity 
{ 
... 
4

Provare a utilizzare il vincolo where: risposta

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware 
    where T : Entity 
{ 
    public T MyEntity; 

    public SomeMethod() 
    { 
     MyEntity.SomeEntityProperty = SomeValue; 
    } 
} 
Problemi correlati