2009-08-25 3 views
2

In C# ist es möglich, ein Objekt zu haben, das mehrere Methodensignaturen für eine Aktion <> oder Delegate hat? Wie folgt aus:C# - Ist es möglich, mehrere Methodensignaturen für eine Aktion <> zu verwenden?

class Foo 
{ 
    public Action<string> DoSomething; 
    public Action<string, string> DoSomething; 
} 

class Bar 
{ 
    public Bar() 
    { 
     Foo f1 = new Foo(); 
     f1.DoSomething = (s) => { Console.Write(s) }; 
     Foo f2 = new Foo(); 
     f2.DoSomething = (s1, s2) => { Console.Write(s1 + s2) }; 

     f1.DoSomething("Hi"); 
     f2.DoSomething("Hi","World"); 
    } 
} 

Die Antwort scheint nicht zu sein, so was ist der richtige Weg, so etwas zu implementieren? (Das eigentliche Problem dieser versuchte, eine andere Art und Weise gelöst zu lösen ist, dies nur Neugier an dieser Stelle)

Antwort

4

A delegate ist eine Abstraktion eines einzigen Methode (natürlich verschiedene Methoden mit ähnlichen Signaturen können sein Es handelt sich dabei um einen einzelnen Delegaten, aber aus der Perspektive des Aufrufers verhält es sich wie eine einzige Methode. Das ist hier irrelevant. Es macht keinen Sinn, wenn eine einzelne Methode mehrere Signaturen hat. Daher hat eine Delegat-Instanz eine bestimmte Signatur. Die Überladungsauflösung hat für Delegierte keine Bedeutung. Es ist keine Methodengruppe, aus der Sie auswählen. Sie zeigen direkt auf eine Methode und sagen "ruf dies an."

Was ist die Lösung für dieses Problem?

Es ist mir nicht klar, was das eigentliche Problem ist. Dies könnte das sein, was Sie suchen:

class Foo { 
    public Action<string> DoSomethingDelegate1; 
    public Action<string,string> DoSomethingDelegate2; 
    public void DoSomething(string s) { DoSomethingDelegate1(s); } 
    public void DoSomething(string s, string t) { DoSomethingDelegate2(s, t); } 
} 

class Bar 
{ 
    public Bar() 
    { 
     Foo f1 = new Foo(); 
     f1.DoSomethingDelegate1 = (s) => { Console.Write(s) }; 
     Foo f2 = new Foo(); 
     f2.DoSomethingDelegate2 = (s1, s2) => { Console.Write(s1 + s2) }; 

     f1.DoSomething("Hi"); 
     f2.DoSomething("Hi","World"); 
    } 
} 
+0

Das ist eigentlich ziemlich nah an dem, was ich gesucht habe (und was ich getan habe), meine Frage war mehr von gab es eine Möglichkeit, die zusätzlichen Funktionen (die "DoSomething" s) zu deklarieren. Ich glaubte nicht, dass es da war, aber ich wollte es bestätigen. – Dugan

0

Der Delegate Typ ist abstrakt und nur die Delegierten auf Basis voll typisierten Signaturen erstellt werden können. So ist es unmöglich, nur einen Delegierten zu jeder Methode zu erstellen, ohne eine Delegate Vorlage bereitstellt, aber es ist immer noch möglich, eine vorhandene Delegattyp zuweisen verwenden, wie Action oder Action<T>:

class Foo 
{ 
    public Delegate Target { get; set; } 

    public void Fire() 
    { 
     if (Target != null) 
     { 
      var pinfos = Target.Method.GetParameters(); 
      object[] args = new object[pinfos.Length]; 
      for (int i = 0; i < pinfos.Length; i++) 
      { 
       // Attempt to create default instance of argument: 
       args[i] = Activator.CreateInstance(pinfos[i].ParameterType); 
      } 
      Target.DynamicInvoke(args); 
     } 
    } 
} 

class Bar 
{ 
    public void Huppalupp() 
    { 
     Foo f = new Foo(); 
     f.Target = new Action(MethodThatTakesNothing); 
     f.Fire(); 
     f.Target = new Action<string>(MethodThatTakesAString); 
    } 

    void MethodThatTakesNothing() 
    { 
     Console.WriteLine("Absolutely nothing."); 
    } 

    void MethodThatTakesAString(string s) 
    { 
     Console.WriteLine(s); 
    } 
} 

Dies kompiliert, aber ich haven habe es nicht für irgendeinen Zweck versucht.

Verwandte Themen