是C#分类列表<;TKey,TValue>;。包含抛出null异常的方法是件好事吗?

是C#分类列表<;TKey,TValue>;。包含抛出null异常的方法是件好事吗?,c#,specifications,sortedlist,C#,Specifications,Sortedlist,考虑这段代码(也可用): 使用系统; 使用System.Collections.Generic; 班级计划{ 静态void Main(){ WriteLine(haseItem(new List(),null)); 试一试{ WriteLine(HasItem(new SortedList().Keys,null)); }捕获(异常){ Console.WriteLine(“ArgumentNullException”); } } 公共静态bool HasItem(ICollection集合,字

考虑这段代码(也可用):

使用系统;
使用System.Collections.Generic;
班级计划{
静态void Main(){
WriteLine(haseItem(new List(),null));
试一试{
WriteLine(HasItem(new SortedList().Keys,null));
}捕获(异常){
Console.WriteLine(“ArgumentNullException”);
}
}
公共静态bool HasItem(ICollection集合,字符串项){
返回集合。包含(项目);
}
}
问题 输出是

假的

无参数异常

在深入研究了如何工作之后,我发现这个调用相当于调用方法,它有一个
ArgumentNullException
文档记录

另一方面,该方法的文档说明:

返回:
true
如果在
i集合中找到项
;否则,
false

在我的示例中,
null
不是第二个集合的一部分,因此我希望返回
false
ArgumentNullException
是对接口的违反,因此是一个bug


生产代码中的解决方法是什么?如果属性返回私有泛型嵌套类的实例,并且我没有其他想法,那么类型检查将非常糟糕。另外,类型检查是一种非常讨厌的代码气味。

SortedList类实现了
IDictionary
,它指定
SortedList
键、值
性质。由于
IDictionary
实现的预期工作方式(利用hashcode对键进行排序或索引),您不能将
null
对象作为键输入,因为
null
没有有效的hashcode。因此,
Contains(…)
方法在尝试将
null
传递到参数时将抛出一个
ArguementInvalidException
,因为它知道
null
不是有效键


如果您想为生产环境“修复”此问题(我不建议这样做,因为这不应该是一个真正的问题),我建议扩展
SortedList
类,并重写
Contains(…)
方法,以便在传递
null
参数时安全返回。

我在MSDN:Type:t上找到这一行 要在集合中定位的对象。对于引用类型,该值可以为null

编辑:您需要System.Linq的using语句

使用System.Linq

       SortedList<string, int> temp = new SortedList<string, int>();
        bool test = HasItem(temp.Keys, null);


    public bool HasItem(ICollection<string> collection, object item)
    {
        return collection.Contains(item);
    }//This returns false when fed a null
SortedList temp=新的SortedList();
布尔测试=HasItem(临时键,空);
公共布尔HasItem(ICollection集合,对象项)
{
返回集合。包含(项目);
}//当输入null时,返回false

我认为,通过使用Object作为参数而不是字符串(字符串是不可变的),我的参数可以真正识别为引用类型。无论采用哪种方式,此功能都经过测试并正常工作。祝你好运。

我想知道你的问题:-)>在生产代码中有什么解决方法?也有点讨厌,但是捕获异常并返回
false
@Jay谢谢,是的,这是一种可能性,但不幸的是,它太广泛了-我只想处理
SortedList
案例
catch(ArgumentNullException){return false;}
?我知道,这也很难看。实际上,我会说contains实现是错误的,因为它应该查看值,而不是键。话虽如此,它是什么,它不会改变,所以代码围绕着它。这都是真的,但这也与最初的问题相去甚远。是的,
SortedList
是一本字典,好吧,但我们这里说的是
SortedList.Keys
,它不是字典,它只是一个集合。另外,我只能访问
HasItem
方法,
Main
方法是消费者定义的代码哦,但它似乎仍然在同一条船上。不同的
包含
方法的状态将利用最适合父对象性质的任何实现(它也明确提到
IDictionary
),显然,
Keys
属性的实现方式可能类似于
ICollection
,但其行为可能更像其父对象
IDictionary
。当然,它最终也可能只是一个.NET的怪癖。您是如何编译它的?
ICollection
没有
Contains(object value)
方法声明我不确定您的意思,但我正在visual studio 2015的asp.net MVC中运行我的代码。我的框架是4.5。您是否在同一个目标框架上运行,这在本例中应该是唯一重要的事情。它编译时没有错误。正如您所看到的,在这个接口中没有这样的方法。您是否100%确定在您的环境中没有为您提供任何扩展方法?好的,我离开并隔离了代码,似乎您需要一个using语句,而您仅仅使用System是无法获得的;使用System.Collections.Generic;您还必须包括System.Linq。但就扩展而言,我编写了很多扩展,但还没有为此编写一个。虽然这确实解决了本例中引发的异常,但代码走的是一条完全不同的道路。如果用户有一个
ICollection
的自定义实现,并将其传递给
HasItem
方法,该怎么办?您提出的方法不会通过此自定义逻辑。
       SortedList<string, int> temp = new SortedList<string, int>();
        bool test = HasItem(temp.Keys, null);


    public bool HasItem(ICollection<string> collection, object item)
    {
        return collection.Contains(item);
    }//This returns false when fed a null