不明确的构造函数调用错误

时间:2014-08-27 13:08:14

标签: c# oop constructor

我有一个名为Test的班级,其中constructor接受Action<T>,另一个班级接受Func<T,T>。请参阅以下代码段。

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

}

但是在行之下引发了一个模糊的调用错误

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

有趣的是,我有两个方法,我的Testconstructor具有相同的签名,不会引起任何歧义错误

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

有人可以帮我识别并解决问题。

4 个答案:

答案 0 :(得分:7)

方法的返回值不是其签名的一部分。仅考虑参数。因此,编译器无法区分Action<T>Func<T,T>。可以找到详细的解释和解决方法in this StackOverflow question

答案 1 :(得分:2)

您可以尝试重命名每个构造函数的参数,如下所示:

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

因此,当您实例化类时,您可以指定参数的名称,如下所示:

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

答案 2 :(得分:1)

<强>事实

方法/构造函数重载可以通过参数类型识别正确的方法,但不包括返回类型。

<强>原因

因为在问题中提到的两个构造函数中,参数都是MethodGroup类型,所以编译器无法确定正确的重载。其次,对方法的调用是成功的,因为它不是超载方案。

解决

以下是解决问题的可能选项

将方法调用包装到匿名方法调用中,让隐式转换区分自己。

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

结果

result


替代方法

其他选项是显式转换方法组

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

如果参数少于

,这比第一种方法要长一些

答案 3 :(得分:0)

这是一个工作控制台应用程序示例

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

希望它会帮助你

问候