111 votes

Pourquoi les classes statiques ne peuvent-elles pas mettre en œuvre des interfaces ?

Duplicata possible :
Pourquoi C# ne permet-il pas aux méthodes statiques d'implémenter une interface ?

Dans mon application, je veux utiliser un référentiel qui fera l'accès aux données brutes ( TestRepository , SqlRepository , FlatFileRepository etc). Étant donné qu'un tel référentiel serait utilisé tout au long de l'exécution de mon application, il m'a semblé judicieux d'en faire une classe statique, de sorte que je puisse faire ce qui suit

SqlRepository.GetTheThingById(5);

sans qu'il soit nécessaire de le régénérer en permanence. Comme je veux que mes référentiels soient interchangeables, je veux qu'ils mettent en œuvre une interface commune : IRepository . Mais quand j'essaie de le faire, j'obtiens :

Les classes statiques ne peuvent pas implémenter les interfaces

Pourquoi ne peuvent-ils pas le faire ? Comment suggérez-vous que je modifie mon design alors ? Y a-t-il un modèle que je pourrais utiliser ?

UPDATE
Cinq ans plus tard : cette question est visitée plus de 20 000 fois, j'ai appris les inconvénients du modèle de dépôt, j'ai appris l'IoC et je me suis rendu compte que ma question était mal formulée.

Je ne demandais pas vraiment ce qu'est la spécification C# d'une interface, mais plutôt pourquoi elle me limitait délibérément de cette manière spécifique.

La réponse pratique est que la syntaxe pour appeler une méthode sur une instance ou sur un type est différente. Mais la question est close.

1 votes

Duplicata de stackoverflow.com/questions/259026 Je pense.

1 votes

Si votre message n'est pas fermé en tant que duplicata, pouvez-vous changer inherit en implement ? C'est un problème pour moi...

0 votes

49voto

Joe White Points 32629

Les interfaces ne peuvent pas avoir de méthodes statiques. Une classe qui implémente une interface doit les implémenter toutes en tant que méthodes d'instance. Les classes statiques ne peuvent pas avoir de méthodes d'instance. QED.

105 votes

Correct mais pas une réponse à la question "pourquoi".

10 votes

En fait, c'est exactement ça. Chaque phrase mène logiquement à la suivante. Relisez sa réponse, analysez-la, laissez-la pénétrer ;-)

40 votes

@Heliac : Ce n'est pas un argument convaincant si le public n'accepte pas les prémisses. Si Boris a compris pourquoi cette prémisse est vraie, pourquoi diable ne comprendrait-il pas pourquoi les classes statiques ne peuvent pas implémenter des interfaces ?

18voto

n8wrl Points 12485

Peut-être que notre expérience vous aidera. Plutôt que d'utiliser SqlRepository comme une classe statique, nous utilisons AutoFac pour l'injection et cachons le conteneur derrière une classe statique. Ensuite, chaque entité a une propriété statique de repository :

public class Part : inheritence...
{
    public static IPartRepository Repository
    {
        get { return IoCContainer.GetInstance<IRepository<Part>>(); }
    }
    // ... more part-y stuff
}

De cette façon, nous pouvons échanger l'implémentation et les appelants savent toujours où la trouver :

Part p = Part.Repository.Get(id);

Dans un autre projet, il y a un PartRepository enregistré avec le conteneur :

public class PartRepository : IPartRepository
{
    // IPartRepository implementation that talks to injected DAL
}

Dans un autre projet encore, nous avons des mocks pour les tests, y compris des référentiels préchargés avec des entiers connus :

public class MockPartRepository : Dictionary<Part, int>, IPartRepository
{
    // IPartRepository implementation based on dictionary
}

...et il est enregistré dans le conteneur pour les tests unitaires. Le MÊME appel obtient le référentiel :

Part p = Part.Repository.Get(id);

0 votes

Pourriez-vous développer ce point ? Un peu plus de code ?

1 votes

@moontear : Nous sommes passés à AutoFac mais le concept est le même. Voir les modifications apportées à la réponse

1 votes

Woah, j'aimerais pouvoir upvoter plus. Mise à jour après 3 ans :-) Nous utilisons Spring.Net et je pense simplement utiliser un singleton (pour le framework de journalisation) au lieu de construire un référentiel complet. Sinon, j'adore votre solution !

14voto

JoshJordan Points 8869

Par définition, les interfaces créent un contrat que les instances doivent remplir. Puisque vous ne pouvez pas instancier une classe statique, les classes statiques ne peuvent pas implémenter d'interfaces.

Il n'est pas nécessaire de disposer d'un référentiel statique. Il suffit de le rendre non statique et de l'instancier lorsque vous en avez besoin.

23 votes

Par définition, les interfaces créent des contacts (par exemple, des méthodes qui peuvent être appelées). Une classe statique possède des méthodes qui peuvent être appelées. Ego : la classe statique peut remplir le contrat.

2 votes

C'est vrai pour la définition d'une interface générique, mais cette question porte sur le C#, où votre définition est incomplète.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X