最小起订量设置不适用于方法调用后跟隐式转换
本文关键字:调用 转换 方法 适用于 不适用 设置 | 更新日期: 2023-09-27 18:32:01
对于这个问题,请考虑(创建)接口:
public interface ITestMe
{
string TakeInt64(long x);
}
然后运行以下代码:
public void Test()
{
var mock1 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr1 = x => x.TakeInt64(2);
Console.WriteLine(expr1);
mock1.Setup(expr1).Returns("OK");
var s1 = mock1.Object.TakeInt64(2L); // OK
var mock2 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr2 = x => x.TakeInt64(DateTime.Today.Year / 1000);
Console.WriteLine(expr2);
mock2.Setup(expr2).Returns("OK");
var s2 = mock2.Object.TakeInt64(2L); // OK
var mock3 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr3 = x => x.TakeInt64((int)(DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Tuesday"));
Console.WriteLine(expr3);
mock3.Setup(expr3).Returns("OK");
var s3 = mock3.Object.TakeInt64(2L); // OK
var mock4 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr4 = x => x.TakeInt64(GetInt32());
Console.WriteLine(expr4);
mock4.Setup(expr4).Returns("OK");
//var s4 = mock4.Object.TakeInt64(2L); // MockException, All invocations on the mock must have a corresponding setup.
var mock5 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr5 = x => x.TakeInt64(int.Parse("2"));
Console.WriteLine(expr5);
mock5.Setup(expr5).Returns("OK");
//var s5 = mock5.Object.TakeInt64(2L); // MockException, All invocations on the mock must have a corresponding setup.
var mock6 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr6 = x => x.TakeInt64(GetInt32() + 0);
Console.WriteLine(expr6);
mock6.Setup(expr6).Returns("OK");
var s6 = mock6.Object.TakeInt64(2L); // OK
var mock7 = new Mock<ITestMe>(MockBehavior.Strict);
Expression<Func<ITestMe, string>> expr7 = x => x.TakeInt64(1 * int.Parse("2"));
Console.WriteLine(expr7);
mock7.Setup(expr7).Returns("OK");
var s7 = mock7.Object.TakeInt64(2L); // OK
}
static int GetInt32()
{
return 2;
}
在所有七种情况下,我们创建一个表达式树,其中TakeInt64
得到一个int
(Int32
)而不是一个long
(Int64
)。但是,众所周知,存在从 int
到 long
的隐式转换,该转换将存在于表达式树中(编译器为我们转换常量expr1
除外)。
为什么上面s4
和s5
的情况不起作用?奇怪的是,如您所见,如果我们像s6
和s7
的情况一样按1
添加 0
或多个,那也有效(即使类型仍然int
,隐式转换为 long
)?
由于案例expr2
,请在 3000 年之前回答。
我认为这是最小起订量中的一个错误。相关代码在MatcherFactory
.具体而言,将从表达式中删除Convert
,以便可以进一步检查它。当剩余的最顶层表达式节点是方法调用时,将延迟计算此节点。当剩余的表达式不是方法调用时,将急切地计算整个表达式(包括Convert
!)。
这意味着使用惰性求值,比较是在没有Convert
的情况下完成的,object.Equals(2, 2L)
是false
的。但是通过急切的评估,Convert
被考虑在内,因此您的代码可以正常工作。
我已经尝试解决此问题,这似乎为我解决了问题。
(呵呵,我差点以为我来不及了。