Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a generic constraint that is a generic type

I have a two generic abstract types: Entity and Association.

Let's say Entity looks like this:

public class Entity<TId>
{ 
//...
}

and Association looks like this:

public class Association<TEntity, TEntity2>
{
//...
}

How do I constrain Association so they can be of any Entity?

I can accomplish it by the following:

public class Association<TEntity, TId, TEntity2, TId2>
     where TEntity : Entity<TId>
     where TEntity2: Entity<TId2>
{
//...
}

This gets very tedious as more types derive from Association, because I have to keep passing down TId and TId2. Is there a simpler way to do this, besides just removing the constraint?

like image 235
moribvndvs Avatar asked Apr 20 '10 18:04

moribvndvs


People also ask

What is generic type constraint?

A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)

How do you indicate that a class has a generic type parameter?

A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.

How do you define generic type?

Definition: “A generic type is a generic class or interface that is parameterized over types.” Essentially, generic types allow you to write a general, generic class (or method) that works with different types, allowing for code re-use.

How do you define a generic type in TypeScript?

Generic types have type parameters that need to be specified before you can use them as a specific type. For example: type GenType<T> = (x: T) => T[]; declare const oops: GenType; // error declare const genT: GenType<string>; // okay const strArr = genT("hello"); // string[]; const numArr = genT(123); // error!


1 Answers

This problem is usually solved by having your generic class (Entity<TId>, in this case) inherit from a common non-generic class.

public abstract class EntityBase
{

}

public class Entity<TId> : EntityBase
{

}

This will allow you to do:

public class Association<TEntity, TEntity2>
    where TEntity : EntityBase
    where TEntity2 : EntityBase
{

}

Edit

If having them inherit from a common class is an issue, then this could be easily done with an interface as well.

like image 174
Adam Robinson Avatar answered Nov 03 '22 22:11

Adam Robinson