114 votes

Comment puis-je implémenter des méthodes statiques sur une interface ?

J'ai une DLL C++ d'un tiers que j'appelle depuis C#.

Les méthodes sont statiques.

Je veux l'abstraire pour faire des tests unitaires et j'ai donc créé une interface avec les méthodes statiques mais maintenant mon programme se plante avec :

Le modificateur 'static' n'est pas valide pour cet article.

MyMethod cannot be accessed with an instance reference; qualify it with a type name instead

Comment puis-je réaliser cette abstraction ?

Mon code ressemble à ceci

private IInterfaceWithStaticMethods MyInterface;

public MyClass(IInterfaceWithStaticMethods myInterface)
{
  this.MyInterface = myInterface;
}

public void MyMethod()
{
  MyInterface.StaticMethod();
}

4 votes

Vous pouvez peut-être le faire avec des méthodes d'extension : stackoverflow.com/questions/1243921/

129voto

Danny Varod Points 8685

Les interfaces ne peuvent pas avoir de membres statiques et les méthodes statiques ne peuvent pas être utilisées comme implémentation des méthodes de l'interface.

Ce que vous pouvez faire, c'est utiliser une implémentation explicite de l'interface :

public interface IMyInterface
{
    void MyMethod();
}

public class MyClass : IMyInterface
{
    static void MyMethod()
    {
    }

    void IMyInterface.MyMethod()
    {
        MyClass.MyMethod();
    }
}

Sinon, vous pouvez simplement utiliser des méthodes non statiques, même si elles n'accèdent à aucun membre spécifique de l'instance.

26 votes

Pour ceux qui se demandent pourquoi on voudrait faire cela, c'est particulièrement utile pour écrire des tests unitaires ou d'intégration pour du code existant qui met en œuvre des méthodes statiques.

0 votes

Cette technique a très bien fonctionné pour la mise en œuvre d'une API RESTful rapide qui avait besoin de faire persister des données mais ne pouvait pas utiliser une base de données. L'implémentation ne fonctionnait qu'avec des objets C# en mémoire, il n'y avait donc pas d'endroit pour stocker les données, mais l'utilisation d'une propriété statique a permis d'éviter le recours à une base de données en mémoire utilisant EF Core ou SQLite.

1 votes

@gware n'est pas la façon dont je recommanderais de résoudre ce problème - essayez plutôt d'injecter la structure de données en mémoire dans le constructeur de la classe non statique. De même, vous pouvez faire en sorte qu'une propriété ordinaire accède à un champ statique (également non recommandé).

60voto

davisoa Points 3559

Vous ne pouvez pas définir de membres statiques sur une interface en C#. Une interface est un contrat pour les cas .

Je vous recommande de créer l'interface comme vous le faites actuellement, mais sans le mot-clé static. Ensuite, créez une classe StaticIInterface qui implémente l'interface et appelle les méthodes statiques C++. Pour effectuer des tests unitaires, créez une autre classe FakeIInterface qui implémente également l'interface, mais qui fait ce dont vous avez besoin pour gérer vos tests unitaires.

Une fois que vous avez défini ces deux classes, vous pouvez créer celle dont vous avez besoin pour votre environnement, et la passer à la fonction MyClass Le constructeur de l'entreprise.

51voto

Alireza Points 31

Vous puede définir des méthodes statiques en c# 8 mais vous devez déclarer un corps par défaut pour celle-ci.

public interface IMyInterface
{
      static string GetHello() =>  "Default Hello from interface" ;
      static void WriteWorld() => Console.WriteLine("Writing World from interface");
}

ou si vous ne voulez pas avoir de corps par défaut, lancez simplement une exception :

public interface IMyInterface
{
      static string GetHello() =>  throw new NotImplementedException() ;
      static void WriteWorld() => throw new NotImplementedException();
}

0 votes

Il semble que les membres statiques dans les interfaces sont plutôt inutiles parce que vous ne pouvez pas y accéder par l'instance de l'interface. Au moins dans C# 8.

6 votes

Du point de vue de l'implémentation de l'interface, vous avez raison. C'est inutile. Mais de cette façon, vous êtes au moins sûr d'avoir une méthode implémentée dans chaque classe qui utilise cette interface. (c'est une sorte d'implémentation optionnelle pour les interfaces)

20voto

leppie Points 67289

Les membres statiques sont parfaitement légaux dans le CLR, mais pas dans le C#.

Vous pourriez mettre en place une colle en IL pour relier les détails de l'implémentation.

Je ne suis pas sûr que le compilateur C# permette de les appeler, cependant ?

Voir : 8.9.4 Définition du type d'interface ECMA-335.

Les types d'interface sont nécessairement incomplets puisqu'ils ne disent rien sur la représentation des valeurs du type d'interface. Pour cette raison, une définition de type d'interface ne doit pas fournir de champs pour les valeurs du type d'interface (c'est-à-dire les champs d'instance), bien qu'elle puisse déclarer des champs statiques (voir §8.4.3).

De même, une définition de type d'interface ne doit pas fournir d'implémentations pour les méthodes sur les valeurs de son type. Cependant, une définition de type d'interface peut définir - et définit généralement - des contrats de méthode (nom et signature de la méthode) qui doivent être mis en œuvre par les types types de support. Une définition de type d'interface peut définir et et implémenter des méthodes statiques (voir §8.4.3) puisque les méthodes statiques sont associées au type d'interface lui-même plutôt qu'à une valeur quelconque du type.

11voto

C# 8 autorise les membres statiques sur les interfaces

À partir de C# 8.0, une interface peut définir une implémentation par défaut pour les membres. Elle peut également définir des membres statiques afin de fournir une implémentation unique pour une fonctionnalité commune.

interface (référence C#)

Par exemple

public interface IGetSomething
{
    public static string Something = "something";
}

var something = IGetSomething.Something;

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