web-dev-qa-db-fra.com

Hériter d'une classe de base générique, appliquer une contrainte et implémenter une interface en C #

C'est une question de syntaxe. J'ai une classe générique qui hérite d'une classe de base générique et applique une contrainte à l'un des paramètres de type. Je veux aussi que la classe dérivée implémente une interface. Pour ma vie, je n'arrive pas à comprendre la syntaxe correcte.

Voici ce que j'ai

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

La première chose qui me vint à l’esprit fut la suivante:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Mais cela est inexact car cela oblige T2 à implémenter à la fois IBar et IFoo et non DerivedFoo à implémenter IFoo.

J'ai essayé un peu de googler, d'utiliser des points, des points-virgules, etc., mais je me suis avéré trop court. Je suis sûr que la réponse est simple comme bonjour.

83
Dan Rigby

Vous incluez toute la signature de votre classe avant de définir des contraintes génériques.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
129
Adam Robinson

Ma recommandation: lorsque vous avez une question sur la syntaxe du langage C #, lisez la spécification. c'est pourquoi nous le publions. Vous voudrez lire la section 10.1.

Pour répondre à votre question spécifique, l'ordre des éléments dans une déclaration de classe est le suivant:

  • attributs, entre crochets
  • modificateurs ("public", "statique", etc.)
  • "partiel"
  • "classe"
  • le nom de la classe
  • une liste de déclarations de paramètres de type, séparées par des virgules, placées entre crochets
  • deux-points suivaient une liste de types de base séparés par des virgules (classe de base et interfaces implémentées, la classe de base doit commencer en premier s'il en existe un)
  • contraintes de paramètre de type
  • le corps de la classe, entouré d'accolades
  • un point-virgule

Tout ce qui est sur cette liste est facultatif, à l'exception de "class", du nom et du corps, mais tout doit apparaître dans cet ordre s'il apparaît.

15
Eric Lippert
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }
6
Stan R.
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Ceci est une extension des réponses existantes. La valeur par défaut est string si vous ne fournissez pas de type. Je n'ai pas implémenté d'interface, mais cela ne devrait pas nécessiter autre chose que d'habitude.

0
user875234