c#中存在歧义问题

  • 本文关键字:问题 歧义 存在 c#
  • 更新时间 :
  • 英文 :


我有以下程序:

    static void Main(string[] args)
    {
        CaptureFunction(MyFunction); // This line gets an error: "The call is ambiguous between the following methods or properties: CaptureFunction(System.Func<object,object>) and CaptureFunction(System.Func<int,int>)"
        CaptureFunction(MyFunction2);
    }
    static void CaptureFunction(Func<object,object> myFunction)
    {
        myFunction.DynamicInvoke(3);
    }
    static void CaptureFunction(Func<int, int> myFunction)
    {
        myFunction.DynamicInvoke(3);
    }
    static object MyFunction(object a)
    {
        if (a is int)
            return ((int) a)*3;
        return 0;
    }
    static int MyFunction2(int a)
    {
        return a * 3;
    }

我想弄清楚为什么我在那一行得到歧义错误。它们显然有两个不同的参数签名。我理解int也可以被装箱成object,但是,如果我传递实际的int值,我将要求c#调用CaptureFunction(Func<int, int>)方法,否则它应该调用其他CaptureFunction()方法。有人可以解释这一点,请提供一个可能的工作围绕?

这是由于。net 4中引入的协方差/协方差。查看这里的信息。因为int可以被转换为object,编译器无法决定你指向哪个函数(因为Func可以被转换为Func)对不起,不是。net 4

以下编译:

static void Main(string[] args)
{
    CaptureFunction((Func<object,object>)MyFunction); // This line gets an error: "The call is ambiguous between the following methods or properties: CaptureFunction(System.Func<object,object>) and CaptureFunction(System.Func<int,int>)"
    CaptureFunction(MyFunction2);
}
static void CaptureFunction(Func<object,object> myFunction)
{
    myFunction.DynamicInvoke(3);
}
static void CaptureFunction(Func<int,int> myFunction)
{
    myFunction.DynamicInvoke(3);
}
static object MyFunction(object a)
{
    if(a is int)
        return ((int)a)*3;
    return 0;
}
static int MyFunction2(int a)
{
    return a * 3;
}

注意转换为Func<object,object>

如果你使用的是c# .net 4.0,请尝试使用动态

    static void CaptureFunction(Func<dynamic, dynamic> myFunction)
    {
        myFunction.DynamicInvoke(3);
    }

如果你没有使用4.0,那么就直接使用对象类型。

    static void CaptureFunction(Func<object, object> myFunction)
    {
        myFunction.DynamicInvoke(3);
    }

删除另一个类型为int的CaptureFunction的重载。

你正在传递一个委托给MyFunction…但是哪一个呢?可能是……都可以。

有超载的CaptureFunction将接受MyFunction签名。所以它无法知道你指的是哪个

似乎给定的函数满足两个委托签名。你可以通过显式声明函数来解决这个问题:

Func<int, int> intFunc = MyFunction2;
Func<object, object> objFunc = MyFunction;
CaptureFunction(intFunc);
CaptureFunction(objFunc);

最新更新