web-dev-qa-db-fra.com

contrainte NOT générique où T:! IEnumerable

Selon le titre, est-il possible de déclarer des contraintes de type-négation dans c # 4?

44
Cel

Non - il n'y a pas de tel concept ni en C # ni dans le CLR.

40
Jon Skeet

Autant que je sache, ce n'est pas possible.

Ce que vous pouvez faire, c'est une vérification à l'exécution:

public bool MyGenericMethod<T>()
{
    // if (T is IEnumerable) // don't do this

    if (typeof(T).GetInterface("IEnumerable") == null)
        return false;

    // ...

    return true;
}
4
Didier Ghys

Je me suis retrouvé à essayer d'implémenter le même cas mentionné dans les commentaires:

void doIt<T>(IEnumerable<T> what) { }
void doIt<T>(T whats) { }

I excepté le code suivant pour référencer la première méthode :

doIt(new List<T>());

Mais il en fait fait référence au second one .

Une solution consiste à cast l’argument comme ceci:

doIt(new List<T>().AsEnumerable<T>());

Le casting pourrait être caché par une autre surcharge:

void doIt<T>(List<T> whats) {
    doIt(whats.AsEnumerable<T>());
}
3
Ricardo Valente

Non, mais il serait possible de vérifier avec un "est" et ensuite le manipuler de manière appropriée ...

0
Jay

Vous utilisez une contrainte afin de vous assurer que le type que vous utilisez possède les propriétés/méthodes/... que vous souhaitez utiliser .

Un générique avec une contrainte de type-négation n’a aucun sens, car il n’est pas utile de connaître l’absence de certaines propriétés/méthodes vous ne voulez pas utiliser .

0
ken2k

une utilisation pour cela serait un type d'option.

public class Option<A,B> 
where A : !B
where B : !A
{
    private readonly A a;
    private readonly B b;

    private Option(){}

    public Option(A a) 
    {
        this.a = a
    }

    public Option(B b)  
    {
        this.b = b
    }
} 

la vérification à l'exécution fonctionnerait bien sûr, mais vous ne bénéficieriez pas de la vérification de type au moment de la compilation. 

0
David