LB40
LB40

Reputation: 12331

Generic interface with generic elements and constraints

I would like to define a generic library containing generic elements :

public interface ILibrary<T>

My generic elements are defined like this :

interface ILibElement<T, IVersion<T>>

I would like to add the constraint saying that elements in the Library must implement ILibElement. So I thought I could change my definition of the ILibrary like this :

public interface ILibrary<T> where T : ILibElement<T, IVersion<T>>

But I must add type parameters. So I thought doing something like :

public interface ILibrary<ILibElement<T, IVersion<T>>>

But T is undefined.

I could not find the right syntax. How could I express such a constraint ?

Upvotes: 2

Views: 132

Answers (3)

supercat
supercat

Reputation: 81247

Generic type parameters must be specified as identifiers; the constraints may use more complex nested formulations, but the parameters themselves must not. If one wanted a generic method which took a parameter of some type Nullable<T>, one wouldn't specify it as:

void ThisWontWork<Nullable<T>>(T it) where T:struct {...}

but instead as:

void ThisWillWork<T>(Nullable<T> it) where T:struct {...}

If your collection may be holding further-qualified generic things which will all be of one type, you may wish to add that type as a type parameter for your collection:

class ListOfLists<T,U> where T:IList<U>

If your collection will be holding things that implement a generic interface with a variety of generic types, but you'll only need to use members which do not involve such types, then you should if possible have the members which don't care about the generic type segregated into their own interface, which could be inherited by the full generic. For example, although Microsoft didn't design their IDictionary this way, it could have been defined as something like (in part:)

interface ICheckIfContained
  { bool Contains(object it); }

interface ICheckIfContained<in T> : ICheckIfContained
  { bool Contains(T it); }

interface IDictionary<in TKey, out TValue> : ICheckIfContained<TKey> ...

If one wants to hold a collection of references to dictionaries purely for the purpose of scanning the keys keys in them, without regard for what those keys would map to, a generic parameter constrained to ICheckIfContained could serve such a purpose.

Upvotes: 1

BRAHIM Kamel
BRAHIM Kamel

Reputation: 13774

I think you can try a logic like this

public interface ILibrary<T,V> where T:ILiBelement<T,V> where T:ILiBelement<T,V> 
    where V:IVersion<V>
{

}
interface ILiBelement<T,V> where V:IVersion<T>
{

}
interface IVersion<T>
{

}

hope this help

Upvotes: 1

Mike Perrenoud
Mike Perrenoud

Reputation: 67918

I believe you're just looking to do this:

where T : ILibElement<T, IVersion<T>>

since ILibElement is expressed as ILibElement<T, IVersion<T>> you just need to specifically implement that interface with the T that you're implementing.

Upvotes: 4

Related Questions