2011-02-10 2 views
3

Вот простой код, где я пытаюсь реализовать какой-то полиморфизм.C# Полиморфизм: функция перегрузки, принимающая делегатов Действие <T> и Func <T,R>?

Вы можете увидеть перегруженную функцию Invoker, принимая Func<T,R> и Action<T> в качестве аргумента.

компилятор говорит, что не может быть составлен из-за неопределенности, если методы INVOKER:

class Program 
{ 
    static void Invoker(Action<XDocument> parser) 
    { 
    } 

    static void Invoker(Func<XDocument,string> parser) 
    { 
    } 

    static void Main(string[] args) 
    { 
     Invoker(Action); 
     Invoker(Function); 
    } 

    static void Action(XDocument x) 
    { 
    } 

    static string Function(XDocument x) 
    { 
     return ""; 
    } 
} 

я получаю 3 ошибки, а не от нее я могу объяснить (!). Вот они:

Ошибка 1 Вызов неоднозначен между следующими методами или свойствами: 'ConsoleApplication3.Program.Invoker (System.Action)' и 'ConsoleApplication3.Program.Invoker (System.Func)' C: \ Users \ i.smagin \ документы \ Visual Studio 2010 \ Projects \ ConsoleApplication3 \ ConsoleApplication3 \ Program.cs 21 4 ConsoleApplication3

Error 2 вызов неоднозначен между следующими методами или свойствами: «ConsoleApplication3.Program .Invoker (System.Action) 'и' ConsoleApplication3.Program.Invoker (System.Func) 'c: \ users \ i.smagin \ documents \ visual studio 2010 \ Projects \ ConsoleApp lication3 \ ConsoleApplication3 \ Program.cs 22 4 ConsoleApplication3

Ошибка 3 'строка ConsoleApplication3.Program.Function (System.Xml.Linq.XDocument)' имеет неправильный тип возвращаемого значения C: \ Users \ i.smagin \ документы \ visual studio 2010 \ Projects \ ConsoleApplication3 \ ConsoleApplication3 \ Program.cs 22 12 ConsoleApplication3

Любые идеи?

+0

Я объединил ваш ответ в качестве дополнительного дополнения к вашему вопросу. Если вы хотите задать совершенно новый вопрос, просто откиньте мое редактирование и сделайте это. Пожалуйста, оставляйте ответы только в качестве ответов. –

+0

Спасибо, Тим! –

ответ

6

Оба

static void Action(XDocument x) 

и

static string Function(XDocument x) 

имеют такую ​​же сигнатуру метода.

Возвращаемое значение не является частью подписи метода. Таким образом, просто наличие другого типа возврата не будет работать. Они должны иметь различное количество параметров или типов параметров, которые должны быть разными.

Поскольку компилятор не может определить, какой из них (метод, который принимает Action или метод, который принимает Func) для использования, вы должны явно указать его:

Invoker(new Action<XDocument>(Action)); 
Invoker(new Func<XDocument, String>(Function)); 

для разрешения неоднозначности.

+0

Означает ли это, что Func Action такие же? Если да, то почему я могу скомпилировать программу без вызова метода Invoker? –

+0

Нет, они не такие. Но компилятор не может понять, какой из них использовать, так как они имеют одинаковые подписи. – decyclone

4

Вы можете вызывать ваши методы так:

public static void Main(string[] args) 
{ 
    Invoker(new Action<XDocument>(Action)); 
    Invoker(new Func<XDocument, string> (Function)); 
} 

Просто, вы должны сообщить компилятору, какой метод вы хотите вызвать.

3

Чуть более элегантное решение с помощью LINQ:

public static void Main(string[] args) 
{ 
    Invoker((xdocument)=>doSomething);  // calls action invoker 
    Invoker((xdocument)=>{return doSomething;}); // calls function invoker 
} 

В конце этого ...сводится к подписям.

+5

Здесь нет LINQ. Lambdas используются в LINQ, но они не LINQ. – NOtherDev

Смежные вопросы