在C#中出现歧义问题

时间:2011-10-28 05:04:14

标签: 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,但是,如果我传递实际的CaptureFunction(Func<int, int>)值,我会在C#之外调用int方法,否则它应该调用另一个CaptureFunction()方法。有人可以解释一下,请提供可能的解决方法吗?

4 个答案:

答案 0 :(得分:3)

这是由于.Net 4中引入的协方差/容差法。有关信息,请参阅here。因为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>

答案 1 :(得分:1)

如果您使用的是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的其他重载。

答案 2 :(得分:0)

你正在为MyFunction传递一个代表......但是哪一个?它可能要么......要么工作。

CaptureFunction有重载可以接受MyFunction签名。所以它无法知道你的意思。

答案 3 :(得分:0)

似乎给定的函数满足两个委托签名。您可以通过明确声明func来解决此问题:

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