Question

Donné:

interface I
{
}

class B: I
{
}

class C: I
{
}

class A
{

    public void Method(B arg)
    {
    }

    public void Method(C arg)
    {
    }

    public void Method(I arg)
    {
       // THIS is the method I want to simplify.
       if (I is B)
       {
          this.Method(arg as B);
       }
       else if (I is C)
       {
          this.Method(arg as C);
       }
    }
}

Je sais qu'il existe de meilleurs moyens de concevoir ce type d'interactions, mais à cause de détails qui prendraient trop de temps pour expliquer ce n'est pas possible. Comme ce modèle sera dupliqué BEAUCOUP de fois, je voudrais remplacer le logique conditionnelle avec une implémentation générique que je pourrais utiliser en une seule ligne. Je ne vois pas de moyen simple d’implémenter cette méthode / classe générique, mais mon instinct me dit que cela devrait être possible.

Toute aide serait appréciée.

Était-ce utile?

La solution

Ce que vous voulez, c'est double envoi et modèle de visiteur en particulier.

Autres conseils

Je mettrais la méthode dans l'interface puis laisserais polymorphism décider de la méthode à appeler

interface I
{
   void Method();
}

class B : I
{
   public void Method() { /* previously A.Method(B) */}
}

class C : I
{
   public void Method() { /* previously A.Method(C) */ }
}

class A
{
   public void Method(I obj)
   { 
     obj.Method();
   }
}

Maintenant, lorsque vous devez ajouter une nouvelle classe, il vous suffit d'implémenter I.Method. Vous n'avez pas besoin de toucher à A.Method.

C'est un peu moche, mais le travail est fait:

public void Method(B arg)
{
  if (arg == null) return;
...
}
public void Method(C arg)
{
  if (arg == null) return;
...
}

public void Method(I arg)
{
  this.Method(arg as B);
  this.Method(arg as C);
}

Je ne pense pas que je le ferais de cette façon, cependant. En fait, ça fait mal de regarder ça. Je suis désolé de vous avoir tous obligé à regarder cela aussi.

interface I
{ 
} 

class B : I
{
}

class C : I
{
}    

class A 
{
    public void Method(B arg)
    {
        Console.WriteLine("I'm in B");
    }

    public void Method(C arg)
    {
        Console.WriteLine("I'm in C");
    }

    public void Method(I arg)
    {
        Type type = arg.GetType();

        MethodInfo method = typeof(A).GetMethod("Method", new Type[] { type });
        method.Invoke(this, new I[] { arg });
    }
}

Il n’existe pas sous une forme commode avec C # - voir ici pour une idée basé sur la correspondance de motif de F #, cela fait exactement ce que vous voulez. Vous pouvez faire certaines choses avec réflexion pour sélectionner la surcharge au moment de l'exécution, mais cela sera très lent et posera de graves problèmes si quelque chose satisfait les deux surcharges. Si vous avez une valeur de retour, vous pouvez utiliser l'opérateur conditionnel;

return (I is B) ? Method((B)I) : ((I is C) ? Method((C)I) : 0);

Encore une fois - pas joli.

Facile. En Visual Basic, je le fais tout le temps en utilisant CallByName.

Sub MethodBase(value as Object)
    CallByName(Me, "RealMethod", CallType.Method, value)

Ceci appellera la surcharge de RealMethod qui correspond le mieux au type de valeur d'exécution.

Je suis sûr que vous pouvez utiliser CallByName à partir de C # en important Microsoft.VisualBasic.Interaction ou en créant votre propre version à l'aide de la réflexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top