为什么Moq有时需要在Return中使用显式类型声明?

时间:2017-08-14 14:14:05

标签: c# generics lambda delegates moq

为什么这不起作用Returns((string food) => eat(food))虽然这不是Returns(food => eat(food))

完整的工作示例:

class Program
{
    static void Main(string[] args)
    {
        var animal = new Mock<IAnimal>();
        Func<string, string> eat = food => $"Nom nom nom {food}";

        // works
        animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat);

        // works
        animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food));

        //cannot convert lambda expression to type 'string' because it is not a delegate type
        animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food));

        //cannot convert lambda expression to type 'string' because it is not a delegate type
        animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}");
    }
}

public interface IAnimal
{
    string Eat(string food);
}

1 个答案:

答案 0 :(得分:1)

回复作为答案,以便我可以粘贴一些代码......

这不是Lasse V. Karlsen建议的超载次数。行为是由于铸造。请参阅以下代码中的评论:

//works because "eat" knows it's own input type
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat);

// works because you are explicitly typing input param
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food));

但是,当你使用lambda表达式时,事情变得有点棘手,因为lambda表达式实际上没有输入类型

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food));
// is equivalent to:
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => {return eat(food); });

但是{return eat(food);}不知道food是什么类型。

因此,当你打电话

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food));
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}");

编译器不知道食物的类型。