C# Language


Exemple

where peut servir à deux fins dans C #: taper la contrainte dans un argument générique et filtrer les requêtes LINQ.

Dans une classe générique, considérons

public class Cup<T>
{
    // ...
}

T s'appelle un paramètre de type. La définition de classe peut imposer des contraintes sur les types réels pouvant être fournis pour T.

Les types de contraintes suivants peuvent être appliqués:

  • type de valeur
  • Type de référence
  • constructeur par défaut
  • héritage et implémentation

type de valeur

Dans ce cas, seules les struct (ceci inclut les types de données «primitifs» tels que int , boolean etc.) peuvent être fournies.

public class Cup<T> where T : struct
{
    // ...
}

Type de référence

Dans ce cas, seuls les types de classe peuvent être fournis

public class Cup<T> where T : class
{
    // ...
}

valeur hybride / type de référence

Il est parfois souhaitable de restreindre les arguments de type à ceux disponibles dans une base de données. Celles-ci sont généralement associées à des types de valeur et à des chaînes. Comme toutes les restrictions de type doivent être respectées, il n'est pas possible de spécifier where T : struct or string (ce n'est pas une syntaxe valide). Une solution consiste à restreindre les arguments de type à IConvertible qui a des types intégrés de "... Booléen, SByte, Octet, Int16, UInt16, Int32, UInt32, Int64, UInt64, Unique, Double, Décimal, DateHeure, Char et Chaîne. " Il est possible que d'autres objets implémentent IConvertible, bien que cela soit rare dans la pratique.

public class Cup<T> where T : IConvertible
{
    // ...
}

constructeur par défaut

Seuls les types contenant un constructeur par défaut seront autorisés. Cela inclut les types de valeur et les classes qui contiennent un constructeur par défaut (sans paramètre)

public class Cup<T> where T : new
{
    // ...
}

héritage et implémentation

Seuls les types qui héritent d'une certaine classe de base ou implémentent une interface donnée peuvent être fournis.

public class Cup<T> where T : Beverage
{
    // ...
}


public class Cup<T> where T : IBeer
{
    // ...
}

La contrainte peut même référencer un autre paramètre de type:

public class Cup<T, U> where U : T
{
    // ...
}

Plusieurs contraintes peuvent être spécifiées pour un argument de type:

public class Cup<T> where T : class, new()
{
    // ...
}

Les exemples précédents montrent des contraintes génériques sur une définition de classe, mais les contraintes peuvent être utilisées partout où un argument de type est fourni: classes, structures, interfaces, méthodes, etc.

where peut aussi être une clause LINQ. Dans ce cas, il est analogue à WHERE en SQL:

int[] nums = { 5, 2, 1, 3, 9, 8, 6, 7, 2, 0 };

var query =
    from num in nums 
    where num < 5
    select num;

    foreach (var n in query)
    {
        Console.Write(n + " ");
    }
    // prints 2 1 3 2 0