Frage

Gegeben:

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);
       }
    }
}

Ich weiß, dass es bessere Möglichkeiten, um diese Art von Wechselwirkungen zu entwerfen, sondern wegen der Details, die zu lange dauern würden, zu erklären, dies nicht möglich ist. Da dieses Muster viele Male dupliziert werden, würde Ich mag die ersetzen bedingte Logik mit einer allgemeinen Implementierung, die ich nur eine Zeile verwenden könnte. Ich kann nicht auf einfache Weise sehen diese allgemeine Methode / Klasse zu implementieren, aber meine Instinkte sagen mir, es sollte möglich sein.

Jede mögliche Hilfe würde geschätzt.

War es hilfreich?

Lösung

Was Sie wollen, ist Double-Dispatch und Besuchermuster insbesondere.

Andere Tipps

würde ich die Methode in der Schnittstelle setzen und dann lassen Polymorphismus entscheiden, welche Methode aufzurufen

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();
   }
}

Wenn Sie nun eine neue Klasse hinzufügen müssen, müssen Sie nur I.Method implementieren. Sie brauchen nicht A.Method zu berühren.

Das ist ein bisschen hässlich, aber es wird die Arbeit getan:

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);
}

Ich glaube nicht, ich würde es auf diese Weise tun, wenn. Es tut weh, tatsächlich auf der Suche. Es tut mir leid ich gezwungen, Sie alle auch, dies zu betrachten.

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 });
    }
}

Es existiert nicht in einem bequemen C # Form withing - hier für eine Idee basierend auf F # 's pattern-Matching, das genau das tut, was Sie wollen. Sie können einige Dinge mit Reflexion tun, um die Überlastung zur Laufzeit zu wählen, aber das wird sehr langsam sein, und haben schwer wiegende Probleme, wenn etwas beide Überlastungen erfüllt. Wenn Sie einen Rückgabewert hätten, könnten Sie den bedingten Operator;

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

Wieder -. Nicht schön

Einfach. In Visual Basic kann ich das die ganze Zeit CallByName verwendet wird.

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

Dies wird die Überlastung der RealMethod nennen, die am ehesten den Laufzeittyp des Wertes übereinstimmt.

Ich bin sicher, dass Sie CallByName von C # durch den Import Microsoft.VisualBasic.Interaction oder indem Sie Ihre eigene Version mithilfe von Reflektion verwenden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top