2013-09-21 2 views
0

Почему следующий вызов неоднозначен:Пасс произвольные действия в том же методе

public class Foo 
{ 
    public void Bar<T> (Action<T> simple); 
    public void Bar<T1, T2> (Action<T1, T2> complex); 
} 

... 

public class Test 
{ 
    public static void MyComplex (string a, string b) { ... } 
} 

... 

foo.Bar(Test.MyComplex); 

Если не было бы ясно компилятором для вызова метода Bar<T1,T2>()?

+0

возможный дубликат [Почему не C# Тип делать вывод из этого, казалось бы, простой, очевидный случай ] (http://stackoverflow.com/questions/6229131/why-cant-c-sharp-infer-type-from-this-seemingly-simple-obvious-case) –

ответ

1

Если удалить этот метод public void Bar<T> (Action<T> simple);, ваш код просто не будет компилироваться, потому что вы получите это исключение:

аргументы типа для метода «Foo.Bar (System.Action)» не может быть выведено из Использование. Попробуйте явно указать аргументы типа .

К сожалению, компилятор не может получить типы из этого метода, и вы должны написать этот код для вызова метода:

new Foo().Bar(new Action<string, string>(Test.MyComplex)); 
+0

Почему компилятор не может использовать статические методы для Действие? Он может сделать то же самое с лямбдами. –

+0

Проблема в том, что вы используете общие параметры, если ваш метод будет выглядеть так: 'void Bar (Action complex)' все будет работать. Используя лямбда, вы будете явно указывать типы явно. –

0

Компилятор пытается вывести общие типы параметров для Bar, но сделать это он должен знать все типы аргументов. Аргумент, который у вас есть (Test.MyComplex), фактически является группой методов, а не делегатом, поэтому компилятор также должен вставлять преобразование в совместимый тип делегата. Однако это невозможно, поскольку он не знает, какие типы делегатов использовать, поскольку вывод типа в методе, который должен быть совместим, еще не завершен. Там проблема с курицей и яйцом, и компилятор отказывается сказать, что вызов неоднозначен. Эрик Липперт указывает на комментарии к очень похожим question, что в простых случаях, подобных этому, он может быть разработан, но за счет усложнения правил разрешения перегрузки.

К сожалению, вы должны сделать что-то, что дает компилятору больше информации:

foo.Bar<string, string>(Test.MyComplex); 

или

Action<string, string> action = Test.MyComplex; 
foo.Bar(action); 
Смежные вопросы