Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify generics class where T should be subclass of other type

Tags:

Here is what I'm trying to do, not even sure if possible..

I'm creating BaseViewModel<T> and I want it to accept types inherited from Entity

Consider this code:

public abstract class BaseViewModel<T> : NotificationObject, INavigationAware {  public T MyEntity;  public SomeMethod() { MyEntity.SomeEntityProperty = SomeValue; }  } 

So, I want to say that my T inherited from Entity and therefore I KNOW that it will have SomeEntityProperty.

Is this possible?

like image 463
katit Avatar asked Oct 18 '11 16:10

katit


People also ask

How do I restrict a generic type in Java?

Java For Testers Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.

Where is generic type constraint?

The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.

How do you define a generic class?

A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.

What is T type in C#?

T is called type parameter, which can be used as a type of fields, properties, method parameters, return types, and delegates in the DataStore class. For example, Data is generic property because we have used a type parameter T as its type instead of the specific data type. Note.


2 Answers

Salvatore's answer is totally correct, I just wanted to describe the concept a little better.

What you need is a "generic type constraint"; to specify that the type used as T must conform to certain behaviors (such as being derived from an object or interface more derived than Object), thus increasing what you are allowed to do with that object without further casting (which is generally to be avoided in generics).

As Salvatore's answer shows, GTCs are defined using the "where" keyword:

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

This GTC basically states that any T must derive (however remotely) from Entity. This allows you to treat T as if it were an Entity (except for instantiation of new Ts; that requires an additional GTC), regardless of how more or less derived the actual generic parameter type is from Entity. You can call any method that appears on Entity, and get/set any field or property.

You can also specify that:

  • The type must be a class (where T:class), or alternately must be a ValueType (where T:struct). This either permits or prevents comparison and assignment of a T instance to null, which also allows or prevents use of the null-coalescing operator ??.
  • The type must have a parameterless constructor (where T:new()). This allows instantiations of Ts using the new keyword, by ensuring at compile-time that all types used as Ts have a constructor that takes no parameters.
like image 85
KeithS Avatar answered Oct 05 '22 12:10

KeithS


public abstract class BaseViewModel<T> :     NotificationObject,     INavigationAware      where T : Entity {      public T MyEntity;      public SomeMethod()     {         MyEntity.SomeEntityProperty = SomeValue;     }  } 
like image 32
Salvatore Previti Avatar answered Oct 05 '22 13:10

Salvatore Previti