我花了两天时间追逐一只邪恶的虫子。我通过这个测试用例来缩小问题范围,演示了实现相同接口的不同集合类的不同行为。具体来说,Contains(null)
会为NullArgumentException
投放ImmutableSortedSet
,但不会针对Array
或可变SortedSet
投放{。}}。
using System.Collections.Generic;
using System.Collections.Immutable;
using Xunit;
public class SortedSetSpec
{
[Fact]
public void WTFNullCheck()
{
var data = new[] {"a", "b", "c", "d"};
SortedSet<string> ss = new SortedSet<string>(data);
ImmutableSortedSet<string> iss = ss.ToImmutableSortedSet();
// This passes
data.Contains(null).Should().BeFalse();
// This passes
ss.Contains(null).Should().BeFalse();
// This throws an exception
iss.Contains(null).Should().BeFalse();
}
}
鉴于所有类Array / SortedSet和ImmutableSortedSet实现ICollection<T>
不应该在Contains(null)
调用上具有相同的行为?
当我将ImmutableSortedSet
数据绑定到列表框的ItemsSource
属性时,错误就会出现。
<ListBox x:Name="ListBox" Margin="2"
ItemsSource="{Binding WorkflowTags}"
SelectedItem="{Binding SelectedTag}" >
</ListBox>
问题在于,在数据绑定代码ListBox(又名Selector)深处某些地方要求集合Contains(null)
??如果我将ImmutableSortedSet
数据绑定,它会崩溃。
这是ImmutableCollections
或WPF
的错误,还是预期的行为,我应该知道比使用ImmutableSortedSet
更好?
导致问题的ImmutableSortedSet
中的代码可以在corefx github repo
/// <summary>
/// See the <see cref="IImmutableSet{T}"/> interface.
/// </summary>
public bool Contains(T value)
{
Requires.NotNullAllowStructs(value, nameof(value));
return _root.Contains(value, _comparer);
}