C# Language Vincoli di tipo (classi e interfacce)

Esempio

I vincoli di tipo sono in grado di forzare un parametro di tipo per implementare una determinata interfaccia o classe.

interface IType;
interface IAnotherType;

// T must be a subtype of IType
interface IGeneric<T>
    where T : IType
{
}

// T must be a subtype of IType
class Generic<T>
    where T : IType
{
}

class NonGeneric
{
    // T must be a subtype of IType
    public void DoSomething<T>(T arg)
        where T : IType
    {
    }
}

// Valid definitions and expressions:
class Type : IType { }
class Sub : IGeneric<Type> { }
class Sub : Generic<Type> { }
new NonGeneric().DoSomething(new Type());

// Invalid definitions and expressions:
class AnotherType : IAnotherType { }
class Sub : IGeneric<AnotherType> { }
class Sub : Generic<AnotherType> { }
new NonGeneric().DoSomething(new AnotherType());

Sintassi per più vincoli:

class Generic<T, T1>
    where T : IType 
    where T1 : Base, new()
{
}

I vincoli di tipo funzionano allo stesso modo dell'ereditarietà, in quanto è possibile specificare più interfacce come vincoli sul tipo generico, ma solo una classe:

class A { /* ... */ }
class B { /* ... */ }

interface I1 { }
interface I2 { }

class Generic<T>
    where T : A, I1, I2
{
}

class Generic2<T>
    where T : A, B //Compilation error
{
}

Un'altra regola è che la classe deve essere aggiunta come primo vincolo e quindi le interfacce:

class Generic<T>
    where T : A, I1
{
}

class Generic2<T>
    where T : I1, A //Compilation error
{
}

Tutti i vincoli dichiarati devono essere soddisfatti simultaneamente affinché una determinata istanza generica funzioni. Non c'è modo di specificare due o più insiemi alternativi di vincoli.