2014-08-27 17 views
13

Ho una classe denominata Test che ha un constructor per accettare Action<T> e l'altra accetta Func<T,T>. Si prega di consultare il frammento di seguito.Errore di chiamata del costruttore ambiguo

public class Test<T> 
{ 
    //constructors 
    public Test() { } 
    public Test(Action<T> action) { } 
    public Test(Func<T, T> action) { } 

    //methods with same signature of constructor 
    public void MyMethod1(Action<T> action) { } 
    public void MyMethod2(Func<T, T> action) { } 
} 


public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     Test<string> t1 = new Test<string>(this.MyMethod1); 
     Test<string> t2 = new Test<string>(this.MyMethod2); 

     Test<string> t = new Test<string>(); 
     t.MyMethod1(MyMethod1); 
     t.MyMethod2(MyMethod2); 
    } 

    public void MyMethod1(string value) { } 
    public string MyMethod2(string value) { return string.Empty; } 

} 

Ma al di sotto di linee getta una chiamata ambigua errore

Test<string> t1 = new Test<string>(this.MyMethod1); 
Test<string> t2 = new Test<string>(this.MyMethod2); 

e il punto interessante è, ho due metodi con la stessa firma del mio Test classe constructor che non gettare alcun errore ambiguo

Test<string> t = new Test<string>(); 
t.MyMethod1(MyMethod1); 
t.MyMethod2(MyMethod2); 

Qualcuno potrebbe aiutarmi a identificare e risolvere il problema.

+0

chiarimento: è la domanda "perché fare le assegnazioni non compilare "o" perché il metodo chiama compilare quando i compiti non lo fanno "? – Jon

+0

Qualcuno con il distintivo d'oro chiudi questo come duplicato di [questo] (http://stackoverflow.com/questions/2057146/compiler-ambiguous-invocation-error-anonymous-method-and-method-group-with-fun) per favore. Riapido per modificare il duplicato suggerito ma non sono autorizzato a farlo :( –

risposta

1

Fatto

metodo/costruttore sovraccarico in grado di riconoscere il metodo corretto per i tipi di parametri, ma non include il tipo di ritorno.

Motivo

E poiché in entrambe le chiamate costruttore menzionati nell'interrogazione parametro è di tipo MethodGroup quindi il compilatore è in grado di determinare il corretto sovraccarichi. in secondo luogo, le chiamate al metodo hanno successo come in uno scenario non sovraccarico.

Risoluzione

qui sono le possibili opzioni per risolvere il problema

avvolgendo la chiamata di metodo in una chiamata di metodo anonimo e lasciare che la conversione implicita di distinguersi.

Test<string> t1 = new Test<string>(s => this.MyMethod1(s)); 
    Test<string> t2 = new Test<string>(s => { return this.MyMethod2(s); }); 

risultato

result


approccio alternativo

altra opzione è quella di lanciare in modo esplicito il gruppo metodo

Test<string> t1 = new Test<string>((Action<string>)this.MyMethod1); 
    Test<string> t2 = new Test<string>((Func<string, string>)this.MyMethod2); 

questo è po 'più a lungo quindi il primo approccio se i parametri sono meno

+0

questo non risponde alla domanda, hai qualche spiegazione sul motivo per cui questo risolve il problema ma le conversioni del gruppo metodo non funzionano? –

+0

I don non voglio passarlo come anonimo ... perché il metodo o la funzione saranno più di 10 righe –

+0

@ Selman22 Non vedo nulla di sbagliato con la correzione, in quanto è in grado di puntare al costruttore appropriato. fare riferimento allo screenshot – pushpraj

2

Si può provare a rinominare i parametri per ciascuno dei vostri costruttori in questo modo:

public class Test<T> 
{ 
    public Test() { } 
    public Test(Action<T> action) { } 
    public Test(Func<T,T> function) { } 
} 

Quindi, quando si istanzia la classe è possibile specificare il nome del parametro in questo modo:

var objectWithAction = new Test<string>(action: Method1); 
var objectWithFunction = new Test<string>(function: Method2); 
7

il valore di ritorno di un metodo non fa parte della sua firma. Sono considerati solo i parametri Quindi, il compilatore non può distinguere tra Action<T> e Func<T,T>.Una spiegazione dettagliata e soluzioni alternative possono essere trovati in this StackOverflow question

+0

Sono d'accordo !, allora perché sta lavorando per i metodi? –

+1

@VimalCK Hai un metodo con nomi diversi. Rinominare i metodi per utilizzare lo stesso nome e provare. Non verrà compilato. –

+0

Sì! . sei corretto –

0

qui un esempio di applicazione console operativa

class Program 
    { 
     static void Main(string[] args) 
     { 
      Test<string> t1 = new Test<string>(action: MyMethod1); 
      Test<string> t2 = new Test<string>(function: MyMethod2); 


      Test<string> t = new Test<string>(); 
      t.MyMethod1(MyMethod1); 
      t.MyMethod2(MyMethod2); 
     } 
     public static void MyMethod1(string value) 
     { 
      Console.WriteLine("my method1 {0}", value); 
     } 
     public static string MyMethod2(string value) 
     { 
      Console.WriteLine("my method2 {0}", value); 
      return string.Empty; 
     } 
    } 
    public class Test<T> 
    { 
     //constructors 
     public Test() { } 
     public Test(Action<T> action) 
     { 

      object args = "action"; 
      action.Invoke((T)args); // here you should invoke the method in order to execute it 
     } 
     public Test(Func<T, T> function) 
     { 
      object args = "function"; 
      function.Invoke((T)args); 
     } 

     //methods with same signature of constructor 
     public void MyMethod1(Action<T> action) 
     { 
      object args = "Method 3"; 
      action.Invoke((T)args); 
     } 
     public void MyMethod2(Func<T, T> action) 
     { 
      object args = "Method 4"; 
      action.Invoke((T)args); 
     } 
    } 

spero che vi aiuterà a

riguarda

Problemi correlati