【问题标题】:C# Polymorphysm: overloading function, accepting delegates Action<T> and Func<T,R>?C# Polymorphysm:重载函数,接受委托 Action<T> 和 Func<T,R>?
【发布时间】:2011-06-24 19:50:06
【问题描述】:

这是一个简单的代码,我尝试在其中实现某种多态性。

您可以看到重载的Invoker 函数,接受Func&lt;T,R&gt;Action&lt;T&gt; 作为参数。

如果 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\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs 21 4 ConsoleApplication3

错误 2 以下方法或属性之间的调用不明确:'ConsoleApplication3.Program.Invoker(System.Action)' 和 'ConsoleApplication3.Program.Invoker(System.Func)' c: \users\i.smagin\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs 22 4 ConsoleApplication3

错误 3 'string ConsoleApplication3.Program.Function(System.Xml.Linq.XDocument)' 返回类型错误 c:\users\i.smagin\documents\visual studio 2010\Projects \ConsoleApplication3\ConsoleApplication3\Program.cs 22 12 ConsoleApplication3

有什么想法吗?

【问题讨论】:

  • 我将您的答案合并为您问题的补充。如果你想问一个全新的问题,只需回滚我的编辑并这样做。请仅将答案作为答案发布。

标签: c# oop c#-4.0 polymorphism


【解决方案1】:

两者

static void Action(XDocument x)

static string Function(XDocument x)

具有相同的方法签名。

返回值不是方法签名的一部分。因此,仅具有不同的返回类型是行不通的。它们必须具有不同数量的参数或参数类型必须不同。

由于编译器无法确定使用哪一个(采用 Action 的方法或采用 Func 的方法),因此您必须明确指定它:

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

解决歧义。

【讨论】:

  • 这是否意味着 Func Action 相同?如果是,那为什么我可以编译程序而不调用方法 Invoker?
  • 不,它们不一样。但是,编译器无法确定使用哪一个,因为它们具有相同的签名。
【解决方案2】:

你可以像这样调用你的方法:

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
    }
    

    最后...归结为签名。

    【讨论】:

    • 这里没有 LINQ。 Lambda 在 LINQ 中使用,但它们不是 LINQ。
    最近更新 更多