关于c#空传播+;空合并运算符
考虑以下代码:关于c#空传播+;空合并运算符,c#,C#,考虑以下代码: //get a list that might be null, empty or valid var myItems = _myRepo.GetForId(someId); if (!myItems?.Any() ?? true) { throw new Exception(); } //valid list 这段代码在开始时可能有点混乱,但可以很好地处理(=短)空列表或空引用 我甚至写了一个简短的单元测试,以确保我没有在这里欺骗自己。它通过了: [Te
//get a list that might be null, empty or valid
var myItems = _myRepo.GetForId(someId);
if (!myItems?.Any() ?? true)
{
throw new Exception();
}
//valid list
这段代码在开始时可能有点混乱,但可以很好地处理(=短)空列表或空引用
我甚至写了一个简短的单元测试,以确保我没有在这里欺骗自己。它通过了:
[TestMethod]
public void SomeOtherTest()
{
//interace that is implemented by _myRepo from code above
var myRepo = Mock.Create<IMyRepo>();
myRepo.Arrange(ar => ar.GetForId(Arg.AnyGuid)).Returns(() => null);
var myItems = myRepo.GetForId(Guid.Empty);
if (!myItems?.Any() ?? true)
{
}
else
{
Assert.Fail();
}
myRepo = Mock.Create<ImyRepo>();
myRepo.Arrange(ar => ar.GetForId(Arg.AnyGuid)).Returns(() => new List<MyItem>());
myItems = myRepo.GetForId(Guid.Empty);
if (!myItems?.Any() ?? true)
{
}
else
{
Assert.Fail();
}
myRepo = Mock.Create<ImyRepo>();
myRepo.Arrange(ar => ar.GetForId(Arg.AnyGuid)).Returns(() => new List<MyItem> {new MyItem()});
myItems = myRepo.GetForId(Guid.Empty);
if (!myItems?.Any() ?? true)
{
Assert.Fail();
}
else
{
}
}
鼠标悬停显示myItems.Count==1
这将导致与else分支进行对话。
我真的不知道这怎么可能
更新:
这可能与您的
状况无关,如果状况如此。也许这与你的GetForId
实现有关?如果你能展示一个令人惊讶的行为,这会更容易理解-只是一个控制台应用,我们可以复制/粘贴/编译/运行。出于调试目的,请执行以下操作:将你的if语句从if(!myItems?.Any()??true)
更改为if(myItems==null | myItems.Count==0)
,然后再次运行测试。如果计算结果为true,则我们知道问题出在其他地方。@JohnLBevan Linq的.Any()如果列表包含任何内容(包括null
),则带有空谓词的扩展名返回true。??
运算符仅在列表本身为null时进行计算。如果myItems
确实有Count==1
,则它将达到else
条件。即使它包含的项为null
。一定还有别的事情发生。请看JonSkeet的请求。
myRepo.Arrange(ar => ar.GetForId(Arg.AnyGuid)).Returns(() => new List<MyItem> {new MyItem()});
myItems = myRepo.GetForId(Guid.Empty);
if (!myItems?.Any() ?? true)
{
//debugger stops here
}
else
{
}