Незначительная ошибка вызова конструктора
У меня есть класс под названием 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);
и интересным моментом является то, что у меня есть два метода с одной и той же сигнатурой моего класса Test
constructor
, который не бросает какую-либо неоднозначную ошибку
Test<string> t = new Test<string>();
t.MyMethod1(MyMethod1);
t.MyMethod2(MyMethod2);
Может ли кто-нибудь помочь мне определить и исправить проблему.
Ответы
Ответ 1
Возвращаемое значение метода не является частью его подписи. Учитываются только параметры. Следовательно, компилятор не может различать Action<T>
и Func<T,T>
. Подробное объяснение и обходные пути можно найти fooobar.com/questions/378929/...
Ответ 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);
Ответ 3
Факт
метод/перегрузка конструктора может распознать правильный метод по типам параметров, но не включает тип возвращаемого значения.
Причина
И поскольку в обоих упомянутых конструкторах в вопросе параметр имеет тип 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);
это бит дольше, чем первый подход, если параметры меньше
Ответ 4
здесь пример рабочего приложения консоли
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);
}
}
надеюсь, что это поможет вам
приветствует