.NET, Architecture, ALM, Cloud

Publicité

Contraintes sur générique en C# 2.0

Mettre en place des classes génériques peut s'avérer très pratique pour vos développements, mais sans utiliser les contraintes (ou restrictions) sur vos types génériques, l'utilisation des génériques devient peu utile.

Les contraintes sur génériques vont vous permettre de définir des restrictions sur vos types pour par exemple définir que le type T doit implémenter l'interface IDisposable. Cela vous permet donc d'imposer dès règles sur vos types génériques mais surtout pouvoir utiliser dans votre classe générique les membres des interfaces et classes définies dans vos contraintes.

Une contrainte est déclaré à partir du mot clef  "where". Vous allez pouvoir à partir de ce mot clef déclarer plusieurs types de contraintes :

  1) "where T :
IDisposable" : Définit que le type générique T doit implémenter l'interface "IDisposable".
  2) "where T :
MyBaseClass" : Définit que le type générique T doit hériter de la classe "MyBaseClass".
  3) "where T : new
()" : Définit que le type générique T peut être instancié. Sans définir cette contrainte, vous n'allez pas pouvoir instancier le type T dans votre classe générique.
  4) "where T :
struct" : Définit que le type générique T doit être un type valeur.
  5) "where T :
class" : Définit que le type générique T doit être un type référence.
  6) "where
T : U" : Définit que le type U doit hériter de T ou du même type de T.

Et voici un rapide cas d'utilisation :

public interface ICriteria { }

public
interface IEntity
{
  void LoadFromRecord(IDataRecord
record);
}

public
abstract class BaseDataAcess<E,C>
  where E : IEntity, new
()
  where C : E,
ICriteria
{
  public List
<E> GetDatas(C criteria)
  {
    List<E> entities = new List
<E>();
    IDataReader
reader = GetReader(criteria);
    try
    {
      while
(reader.Read())
      {
        E entity =
new
E();
        entity.LoadFromRecord(reader);
        entities.Add(entity);
      }
    }
    finally
    {
       reader.Close();
    }
    return
entities;
  }

  protected abstract IDataReader
GetReader(C criteria);
}
 

Nous avons donc dans cet exemple une classe abstraite d'accès aux données qui attend une entité qui peut être chargé à partir d'un reader et un objet de critère qui doit hériter de l'entité passé à la classe générique. La méthode "GetDatas" retourne une liste d'entités et comme vous pouvez le voir, le fait d'avoir ajouté la contrainte sur "IEntity" nous permet de faire appel à la méthode "LoadFromRecord" depuis notre entité et de l'instancier grâce à la contrainte "new()".

Publicité
Retour à l'accueil
Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article