ReSharper错误地声称IDictionary.Values始终为非null

时间:2018-07-25 13:10:00

标签: c# resharper postsharp

我得到了以下代码:

    public IEnumerator<TRow> GetEnumerator()
    {
        if (this._rows.Values == null) return Enumerable.Empty<TRow>().GetEnumerator();

        return this._rows.Values.GetEnumerator();
    }

Resharper告诉我_rows.Values始终不为null(因为我使用的IDictionary的实现-PostSharps AdvisableDictionary来自此处http://doc.postsharp.net/t_postsharp_patterns_collections_advisabledictionary_2,所以情况并非如此)往往在创建后立即返回null(我猜很尴尬的实现-我不知道为什么他们会这样实现)。

enter image description here

无论我使用哪种IDictionary实施-ReSharper为什么期望该实施以这种方式工作?没有人可以保证这是真的。还是我做错了什么?

按照“注释:显示行为的最小实现”中的要求(在return Enumerable.Empty<TRow>().GetEnumerator()上设置一个断点,该点由resharper变灰):

 class Program
{
    static void Main(string[] args)
    {
        var model = new Model();

        bool any = model.Any();
    }
}

[NotifyPropertyChanged]
public class Model : IEnumerable<string>
{
    private IDictionary<string, string> dictionary;

    public Model()
    {
        dictionary = new AdvisableDictionary<string, string>();
    }

    public IEnumerator<string> GetEnumerator()
    {
        if (dictionary.Values == null) return Enumerable.Empty<string>().GetEnumerator();
        return dictionary.Values.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

此示例需要PostSharp.Patterns.Model软件包和PostSharp许可证(有试用版),或将AdvisableDictionary换成自定义词典,该词典在Values吸气剂上返回null。

2 个答案:

答案 0 :(得分:4)

在较新的referencesource中,Microsoft添加了一些涵盖IDictionary<,>的代码合同:

// Returns a collections of the values in this dictionary.
ICollection<TValue> IDictionary<TKey, TValue>.Values {
    get {
        Contract.Ensures(Contract.Result<ICollection<TValue>>() != null);
        return default(ICollection<TValue>);
    }
}

根据该合同,很明显Values不能为null(请注意,它是mustn't,而不是can't :-)破碎的实现IDictionary<,>可以返回null,并且运行时不会捕获它。)

答案 1 :(得分:1)

它始终为true,因为.Values总是返回某些值(值中的集合)。如果您的Dictionary应该为空,则Values-Collection也为空。如果字典为null,则将有NullPointerException,因为值不指向任何对象。