我一直在找你,有些代码无效.除了下面的一行,一切看起来都很好.
Transport = Transport?? MockITransportUtil.GetMock(true);
Run Code Online (Sandbox Code Playgroud)
执行该行之前,Transport为null.我看到GetMock已执行,并且它返回一个非null对象.在该行之后,运输仍为空;
我看了生成的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
Run Code Online (Sandbox Code Playgroud)
我们看到函数被调用,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 …Run Code Online (Sandbox Code Playgroud) 最近,我的同事向我展示了一段无法正常工作的代码:
public class SomeClass
{
private IList<Category> _categories;
public void SetCategories()
{
_categories = GetCategories() ?? new List<Category>();
DoSomethingElse();
}
public IList<Category> GetCategories()
{
return RetrieveCategories().Select(Something).ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
(我知道运算符是多余的,因为linq ToList将始终返回一个列表,但这就是代码的设置方式).
问题是_categories为null.在调试器中,设置断点_categories = GetCategories() ?? new List<Category>(),然后单步执行DoSomethingElse(),_ categories仍然为null.
直接将_categories设置为GetCategories()工作正常.拆分?在一个完整的if语句工作正常.空合并运算符没有.
它是一个ASP.NET应用程序,所以一个不同的线程可能会干扰,但它在他的机器上,只有他在浏览器中连接._cateogories不是静态的,或任何东西.
我想知道的是,这怎么可能发生?
编辑:
只是为了增加奇异性,除了初始化类_categories之外,永远不会设置除该功能之外的任何地方.
确切的代码是这样的:
public class CategoryListControl
{
private ICategoryRepository _repo;
private IList<Category> _categories;
public override string Render(/* args */)
{
_repo = ServiceLocator.Get<ICategoryRepository>();
Category category = _repo.FindByUrl(url);
_categories = _repo.GetChildren(category) …Run Code Online (Sandbox Code Playgroud)