我一直在查看一些代码,但有一部分无法正常工作。除了下面这行代码之外,其他都看起来没问题。
Transport = Transport?? MockITransportUtil.GetMock(true);
在执行那行代码之前,Transport是空的。我看到GetMock被执行并且返回了一个非空对象。但在那行代码之后,Transport仍然为空。
我查看了生成的IL代码,觉得没问题。
IL_0002: ldarg.0
IL_0003: ldfld class [Moq]Moq.Mock`1<class [CommLibNet]CommLibNET.ITransport> Curex.Services.Common.UnitTests.Messaging.TestIGuaranteedSubscriptionBase::Transport
IL_0008: dup
IL_0009: brtrue.s IL_0012
IL_000b: pop
IL_000c: ldc.i4.1
IL_000d: call class [Moq]Moq.Mock`1<class [CommLibNet]CommLibNET.ITransport> Curex.Services.Common.UnitTests.Mocking.MockITransportUtil::GetMock(bool)
IL_0012: stfld class [Moq]Moq.Mock`1<class [CommLibNet]CommLibNET.ITransport> Curex.Services.Common.UnitTests.Messaging.TestIGuaranteedSubscriptionBase::Transport
我们看到函数被调用,stfld应该使用返回值来设置字段。
然后我查看了汇编代码,看到调用被执行,但是似乎RAX中的返回值被下一次调用覆盖并丢失了。
Transport = Transport?? MockITransportUtil.GetMock(true);
000007FE9236F776 mov rax,qword ptr [rbp+0B0h]
000007FE9236F77D mov rax,qword ptr [rax+20h]
000007FE9236F781 mov qword ptr [rbp+20h],rax
000007FE9236F785 mov rcx,qword ptr [rbp+20h]
000007FE9236F789 mov rax,qword ptr [rbp+0B0h]
000007FE9236F790 mov qword ptr [rbp+28h],rax
000007FE9236F794 test rcx,rcx
000007FE9236F797 jne 000007FE9236F7AC
000007FE9236F799 mov cl,1
000007FE9236F79B call 000007FE92290608
//var x = ReferenceEquals(null, Transport) ? MockITransportUtil.GetMock(true) : Transport;
ListerFactory = ListerFactory ?? MockIListenerUtil.GetMockSetupWithAction((a) => invokingAction = a);
000007FE9236F7A0 mov qword ptr [rbp+30h],rax
000007FE9236F7A4 mov rax,qword ptr [rbp+30h]
000007FE9236F7A8 mov qword ptr [rbp+20h],rax
000007FE9236F7AC mov rcx,qword ptr [rbp+28h]
如果我使用if语句或?:运算符,一切都正常工作。
Visual Studio 2013
编辑
我已经创建了一个伪最小化的复制。
class simple
{
public A MyA = null;
public B MyB = null;
public void SetUp()
{
MyA = MyA ?? new A();
MyB = new B();// Put breakpoint here
}
}
如果您在指定行上设置断点并在调试器中查看MyA的值,它仍将为null(仅在x64构建时)。如果执行下一行,则会设置该值。我无法重现完全没有评估发生的情况。很明显,在分解中,下一行的执行已经开始,在赋值之前。
编辑2
这里是ms connect网站的link链接
double? x
- 类似于x = x ?? 1.0;
。如果在达到该行时x
是null
,那么之后它仍然是null
。 - Timothy Shields