如何将谓词<t>转换为表达式<predicate <t>&gt;与Moq一起使用?</predicate <t> </t>

时间:2010-10-21 14:32:52

标签: c# linq lambda moq

请帮助这个Linq新手!

我正在测试中的类中创建一个列表,我想使用Moq检查结果。

我可以很容易地组合一个检查列表结果的谓词。然后,我如何将该谓词变成表达式?

var myList = new List<int> {1, 2, 3};

Predicate<List<int>> myPredicate = (list) => 
                  {
                      return list.Count == 3; // amongst other stuff
                  };

// ... do my stuff

myMock.Verify(m => m.DidStuffWith(It.Is<List<int>>( ??? )));

???需要是Expression<Predicate<List<int>>>,如果你可以了解许多仿制药。我找到了相反的答案,并将表达式编译成谓词。但是,他们并没有帮助我更好地理解Linq。

编辑:我已经使用了方法;表达;我想知道是否有办法用一个带有身体的lambda做 - 如果没有,为什么不呢?

2 个答案:

答案 0 :(得分:5)

变化:

Predicate<List<int>> myPredicate = (list) => list.Count == 3;

要:

Expression<Predicate<List<int>>> myPredicate = (list) => list.Count == 3;

编译器为您带来了魔力。通过一些警告 1 ,任何只处理表达式(无块)的lambda都可以通过包装委托类型(在本例中为Predicate<List<int>>)转换为表达式树)Expression<>。如您所述,您可以通过调用myPredicate.Compile()再次将其反转。

1 例如,async lambdas(即async () => await Task.Delay(1);)无法转换为表达式树。

更新如果包含语句,您只需无法使用编译器到达所需的表达式树。您必须使用Expression中的静态方法自己构建表达式树(更多工作)。 (Expression.BlockExpression.IfThen等。)

答案 1 :(得分:1)

Kirk Woll的回答直接解决了您的问题,但考虑到您可以在Callback方法的Setup上使用void方法来处理传入的参数调用。这对我来说更有意义,因为你已经不得不构建一个方法来验证列表;它还为您提供了列表的本地副本。

//what is this list used for?
var myList = new List<int> {1, 2, 3};

List<int> listWithWhichStuffWasDone = null;
//other setup

myMock.Setup(m => m.DoStuffWith(It.IsAny<List<int>>()).
    Callback<List<int>>(l => listWithWhichStufFWasDone = l);

objectUnderTest.MethodUnderTest();

myMock.Verify(m => m.DoStuffWith(It.IsAny<List<int>>()));
Validate(listWithWhichStuffWasDone);