web-dev-qa-db-fra.com

Implémenter une interface avec des méthodes génériques

Je dessine un vide sur celui-ci et ne semble pas trouver d'exemple précédent que j'ai écrit. J'essaie d'implémenter une interface générique avec une classe. Lorsque j'implémente l'interface, je pense que quelque chose ne fonctionne pas correctement, car Visual Studio génère continuellement des erreurs indiquant que je n'implémente pas toutes les méthodes de l'interface générique.

Voici un bout de ce avec quoi je travaille:

public interface IOurTemplate<T, U>
{
    IEnumerable<T> List<T>() where T : class;
    T Get<T, U>(U id)
        where T : class
        where U : class;
}

À quoi devrait ressembler ma classe?

53
Jason N. Gaylord

Vous devriez retravailler votre interface, comme ceci:

public interface IOurTemplate<T, U>
        where T : class
        where U : class
{
    IEnumerable<T> List();
    T Get(U id);
}

Ensuite, vous pouvez l'implémenter en tant que classe générique:

public class OurClass<T,U> : IOurTemplate<T,U>
        where T : class
        where U : class
{
    IEnumerable<T> List()
    {
        yield return default(T); // put implementation here
    }

    T Get(U id)
    {

        return default(T); // put implementation here
    }
}

Ou, vous pouvez le mettre en œuvre concrètement:

public class OurClass : IOurTemplate<string,MyClass>
{
    IEnumerable<string> List()
    {
        yield return "Some String"; // put implementation here
    }

    string Get(MyClass id)
    {

        return id.Name; // put implementation here
    }
}
93
Reed Copsey

Je pense que vous voulez probablement redéfinir votre interface comme ceci:

public interface IOurTemplate<T, U>
    where T : class
    where U : class
{
    IEnumerable<T> List();
    T Get(U id);
}

Je pense que vous voulez que les méthodes utilisent (réutilisent) les paramètres génériques de l'interface générique dans laquelle elles sont déclarées; et que vous ne voulez probablement pas en faire des méthodes génériques avec leurs propres paramètres génériques (distincts de l'interface).

Étant donné l'interface telle que je l'ai redéfinie, vous pouvez définir une classe comme celle-ci:

class Foo : IOurTemplate<Bar, Baz>
{
    public IEnumerable<Bar> List() { ... etc... }
    public Bar Get(Baz id) { ... etc... }
}

Ou définissez une classe générique comme celle-ci:

class Foo<T, U> : IOurTemplate<T, U>
    where T : class
    where U : class
{
    public IEnumerable<T> List() { ... etc... }
    public T Get(U id) { ... etc... }
}
11
ChrisW

-- Modifier

Les autres réponses sont meilleures, mais notez que VS peut implémenter l'interface pour vous, si vous ne savez pas à quoi cela devrait ressembler.

Processus décrit ci-dessous.

Eh bien, Visual Studio me dit que cela devrait ressembler à ceci:

class X : IOurTemplate<string, string>
{
    #region IOurTemplate<string,string> Members

    IEnumerable<T> IOurTemplate<string, string>.List<T>()
    {
        throw new NotImplementedException();
    }

    T IOurTemplate<string, string>.Get<T, U>(U id)
    {
        throw new NotImplementedException();
    }

    #endregion
}

Notez que je n'ai fait qu'écrire l'interface, puis cliquez dessus et attendez que la petite icône apparaisse pour que VS génère l'implémentation pour moi :)

1
Noon Silk