50 votes

Interfaces C # avec des méthodes optionnelles

Je comprends que les interfaces sont les contrats et tous les changements (même ajouts) pause tout dépendant de code. Cependant, j'aurais juré que j'ai lu quelque chose d'un temps que l'une des dernières .NET versions (3, 3.5??) ajout d'un nouvel attribut qui pourrait être appliquée à de nouveaux membres d'interface. Cet attribut a permis de contrôle de version et/ou les membres de l'option. Il aurait été quelque chose comme:

interface ITest
{
    void MethodOne();

    [InterfaceVersion(2)]
    void MethodTwo();
}

J'ai cherché haut et bas pour cela, mais n'arrive pas à le trouver. Je me demande si j'ai tout simplement mal compris ce que je pense que je l'ai lu et il n'y a pas une telle chose. Quelqu'un avez des idée?

53voto

Lasse V. Karlsen Points 148037

Vous devez créer deux interfaces:

 interface ITest
{
    void MethodOne();
}

interface ITest2 : ITest
{
    void MethodTwo();
}
 

Cela indiquerait également clairement quelles fonctionnalités nécessitent quelle version de vos interfaces, afin que vous n'ayez pas à vérifier si la classe implémentant l'interface implémente une seule méthode, ou les deux.

11voto

Kilhoffer Points 13430

Je n'ai pas vu un tel attribut, mais je suppose que c'est possible. Cet article sur MSDN décrit versioning grâce à l'utilisation de l' overrides et new mots-clés.

En bref, C# est équipé avec des fonctionnalités de langage qui permettent de classes dérivées d'évoluer et de toujours maintenir la compatibilité. Cet exemple montre purement base de dérivés de la relation, mais la base serait effectivement mettre en œuvre l'interface que vous avez besoin de la version. Avoir une interface de demander à une autre (la version précédente) interface couplé avec cette méthode est très utile aussi.

Exemple de création d'une interface qui nécessite un autre:

public interface IMyInterface
{
  void FirstMethod();
}

public interface IMySecondInterface : IMyInterface
{
  void SecondMethod();
}

Exemple de l'utilisation de l'héritage pour maintenir la compatibilité:

public class MyBase 
{
   public virtual string Meth1() 
   {
      return "MyBase-Meth1";
   }
   public virtual string Meth2() 
   {
      return "MyBase-Meth2";
   }
   public virtual string Meth3() 
   {
      return "MyBase-Meth3";
   }
}

class MyDerived : MyBase 
{
   // Overrides the virtual method Meth1 using the override keyword:
   public override string Meth1() 
   {
      return "MyDerived-Meth1";
   }
   // Explicitly hide the virtual method Meth2 using the new
   // keyword:
   public new string Meth2() 
   {
      return "MyDerived-Meth2";
   }
   // Because no keyword is specified in the following declaration
   // a warning will be issued to alert the programmer that 
   // the method hides the inherited member MyBase.Meth3():
   public string Meth3() 
   {
      return "MyDerived-Meth3";
   }

   public static void Main() 
   {
      MyDerived mD = new MyDerived();
      MyBase mB = (MyBase) mD;

      System.Console.WriteLine(mB.Meth1());
      System.Console.WriteLine(mB.Meth2());
      System.Console.WriteLine(mB.Meth3());
   }
}

6voto

Eric Lippert Points 300275

Vous êtes peut-être penser à la nouvelle "aucun pia" fonctionnalité de C# 4? C'est, nous vous permettons de "lien", seules les parties de l'interface que vous utilisez réellement à partir d'un PIA, et puis vous pouvez passer de l'expédition du PIA à vos clients. Ensuite, si vous faites cela plusieurs fois dans les différentes assemblées, le CLR fait le travail de comprendre que tous ceux qui sont liés-en partie les interfaces sont logiquement le même type, et les unifie. De cette façon, vous pouvez passer des objets qui mettent en œuvre chaque saveur de l'interface à partir d'un assemblage à l'autre et tout fonctionne. Cependant, l' origine des interfaces que le "non pia" interfaces sont créés de a à faire de même.

5voto

Jorge Córdoba Points 18919

Il n'y a pas un tel attribut dans le framework .NET.

5voto

David Morton Points 10519

Je ne connais aucun attribut de ce type permettant à une implémentation d'interface d'être partiellement implémentée. Vous pouvez cependant contourner ce problème en utilisant une classe abstraite:

 public abstract class Test
{
     public abstract void MethodOne();
     public virtual void MethodTwo() { }
}
 

Cela permettrait à l'utilisateur de décider s'il souhaite ou non substituer MethodTwo lors de l'héritage de Test, tout en forçant le remplacement de MethodOne.

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