ReSharper 错误地声称 IDictionary.Values 总是非空的
ReSharper wrongly claims that IDictionary.Values is always non null
我得到以下代码:
public IEnumerator<TRow> GetEnumerator()
{
if (this._rows.Values == null) return Enumerable.Empty<TRow>().GetEnumerator();
return this._rows.Values.GetEnumerator();
}
Resharper 告诉我 _rows.Values 总是非空的(事实并非如此,因为我使用的 IDictionary 的实现 - PostSharps AdvisableDictionary
从这里 http://doc.postsharp.net/t_postsharp_patterns_collections_advisabledictionary_2)倾向于 return 创建后立即为空(我猜这是非常尴尬的实现——我不知道他们为什么这样实现)。
无论我使用什么 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
换成 return 在 [= 上为空的自定义词典17=] getter.
它总是 true
因为 .Values
总是 returns 一些东西(从值中收集)。如果您的 Dictionary 应该为空,则 Values-Collection 也为空。如果字典是 null
,则会有一个 NullPointerException
,因为值不引用任何对象。
在较新的 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<,>
的实现可以 return null
并且不会被运行时捕获。
我得到以下代码:
public IEnumerator<TRow> GetEnumerator()
{
if (this._rows.Values == null) return Enumerable.Empty<TRow>().GetEnumerator();
return this._rows.Values.GetEnumerator();
}
Resharper 告诉我 _rows.Values 总是非空的(事实并非如此,因为我使用的 IDictionary 的实现 - PostSharps AdvisableDictionary
从这里 http://doc.postsharp.net/t_postsharp_patterns_collections_advisabledictionary_2)倾向于 return 创建后立即为空(我猜这是非常尴尬的实现——我不知道他们为什么这样实现)。
无论我使用什么 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
换成 return 在 [= 上为空的自定义词典17=] getter.
它总是 true
因为 .Values
总是 returns 一些东西(从值中收集)。如果您的 Dictionary 应该为空,则 Values-Collection 也为空。如果字典是 null
,则会有一个 NullPointerException
,因为值不引用任何对象。
在较新的 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<,>
的实现可以 return null
并且不会被运行时捕获。