2011-10-18 9 views
10

Oto, co usiłuję zrobić, nawet nie jestem pewien, czy to możliwe ..Określić klasy generyczne gdzie T powinien być podklasą innego rodzaju

Tworzę BaseViewModel<T> i chcę go zaakceptować typy odziedziczone Entity

Rozważmy następujący kod:

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

public T MyEntity; 

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

} 

Tak, chcę powiedzieć, że moja T odziedziczone Entity i dlatego wiem, że będzie to miało SomeEntityProperty.

Czy to możliwe?

Odpowiedz

18

Salvatore jest całkowicie poprawna, chciałem po prostu opisać koncepcję trochę lepiej.

Potrzebne jest "ogólne ograniczenie typu"; aby określić, że typ używany jako T musi być zgodny z określonymi zachowaniami (np. pochodzącymi z obiektu lub interfejsu bardziej pochodnego niż Object), zwiększając w ten sposób to, co możesz zrobić z tym obiektem bez dalszego rzucania (którego zasadniczo należy unikać w rodzajach ogólnych).

Jak pokazuje odpowiedziami Salvatore, OWS są definiowane za pomocą słowa kluczowego „gdzie”:

public abstract class BaseViewModel<T> : 
    NotificationObject, 
    INavigationAware 

    where T : Entity; 
{ 
    ... 

GTC to w zasadzie stanowi, że każde T musi pochodzić (jednak zdalnie) od podmiotu. Pozwala to traktować T tak, jakby był Entity (z wyjątkiem tworzenia nowego Ts, który wymaga dodatkowego GTC), niezależnie od tego, w jaki sposób bardziej lub mniej wyprowadzono faktyczny rodzaj parametru generycznego z Entity. Możesz wywołać dowolną metodę, która pojawia się w Entity i pobrać/ustawić dowolne pole lub właściwość.

Można również określić, że:

  • typ musi być klasą (where T:class) lub przemiennie muszą być ValueType (where T:struct). Umożliwia to lub uniemożliwia porównywanie i przypisywanie wystąpienia T do wartości zerowej, co również pozwala lub uniemożliwia użycie operatora koalescencyjnego zerowania.
  • Typ musi mieć konstruktora określonego podpisu (where T:new(), where T:new(int,float)). Pozwala to na tworzenie wystąpień Ts za pomocą słowa kluczowego new, zapewniając w czasie kompilacji, że wszystkie typy używane jako Ts mają konstruktor o oczekiwanej sygnaturze.
11
public abstract class BaseViewModel<T> : 
    NotificationObject, 
    INavigationAware 

    where T : Entity 
{ 

    public T MyEntity; 

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

} 
5

Wystarczy użyć where kluczowe:

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

Spróbuj użyć where ograniczenia: odpowiedź

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

    public SomeMethod() 
    { 
     MyEntity.SomeEntityProperty = SomeValue; 
    } 
} 
Powiązane problemy