Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous constructor call error

I have a class called Test which has a constructor to accept Action<T> and the other one accepts Func<T,T>. Please see the below snippet.

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

}

But below lines throws an ambiguous call error

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

and the interesting point is, I have two methods with the same signature of my Test class constructor which not throwing any ambiguous error

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

Could anyone please help me to identify and fix the issue.

like image 987
Vimal CK Avatar asked Aug 27 '14 13:08

Vimal CK


2 Answers

The return value of a method is not part of its signature. Only the parameters are considered. Hence, the compiler cannot distinguish between Action<T> and Func<T,T>. A detailed explanation and workarounds can be found in this StackOverflow question

like image 91
WeSt Avatar answered Nov 16 '22 16:11

WeSt


You can try renaming the parameters for each of your constructors like so:

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

So when you instantiate your class you can specify the name of the parameter like so:

var objectWithAction = new Test<string>(action: Method1);
var objectWithFunction = new Test<string>(function: Method2);
like image 2
ngergo6 Avatar answered Nov 16 '22 17:11

ngergo6