c# - 代码分析:CA1002:不要公开通用列表。如何理解这种违规行为
问题描述
我已经阅读了很多关于 Do Not Expose Generic 的帖子,但我仍然没有得到确切的分辨率。我编写了一个示例控制台应用程序,它分别使用 List 和 List 作为返回类型和参数。在运行代码分析时,它会显示Do Not Expose Generic List。正如 msdn 所说:
System.Collections.Generic.List<T>
是为性能而非继承而设计的通用集合。System.Collections.Generic.List<T>
不包含使继承类的行为更容易更改的虚拟成员。以下泛型集合是为继承而设计的,应该公开而不是System.Collections.Generic.List<T>
.
修复是
若要修复违反此规则的情况,请将
System.Collections.Generic.List<T>
类型更改为为继承而设计的通用集合之一。
如果我使用System.Collections.Generic.ICollection<T>
. 即使在函数调用者之后,我仍然可以添加项目。那么通用集合有什么用。下面是代码:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public static List<Person> AddPersonsToCurrentList(List<Person> personsList )
{
personsList.Add(new Person(){ Age = 11, Name = "Vijay" });
return personsList;
}
}
public class Program
{
public static void Main(string[] ar)
{
var personList = new List<Person>()
{
new Person(){Age =10,Name="Vj"}
};
var resultList = Person.AddPersonsToCurrentList(personList);
Console.WriteLine(personList.GetType());
personList.Add(new Person(){Age = 11, Name = "Ajay"});
Console.ReadKey();
}
}
现在,如果我将返回类型更改为Collection<Person>
并将参数更改为Collection<Person>
输出是相同的。当我们公开一个通用列表时,我将返回类型和参数列表更改为ICollection<Person>
/ IEnumerable
。如果我把ICollection
. 在该方法之后,我仍然可以向其中添加项目。修改代码:
public static ICollection<Person> AddPersonsToCurrentList(Collection<Person> personsList )
{
personsList.Add(new Person(){ Age = 11, Name = "Vijay" });
return personsList;
}
但是我仍然公开了通用集合,用户仍然可以在调用该方法之前或之后添加项目。任何人都可以帮助我与性能和其他各种其他属性List<T>
相比如何有用。Collection<T>
这对我有很大帮助。提前致谢
解决方案
您被警告 List 对象不灵活,并且您正在限制外部开发人员使用该具体类型。通常,在开发可供其他开发人员使用的代码时,最佳实践是要求尽可能抽象的实现,只实现方法中需要的功能。
如果需要,这允许最终用户提供他们自己的实现。例如,如果您在方法中所做的只是枚举列表,则List<Person>
可以改为依赖于,而不是要求 type 。IEnumerable<Person>
这为您的 API 用户提供了实现自己的 List 类型/帮助程序的灵活性,并且只要他们从 IEnumerable 继承(这是保证您可以通过您的类型枚举的合同),它们仍然可以正常工作。
在您的示例中,您要求 T 类型的 List或从 T 类型的 List 继承的东西,并且被警告List<T>
不应将具体类型用于继承。
推荐阅读
- python - 无法使用网页中的scrapy提取javascript
- vb.net - 在 Visual Basic .net 中使用 HID 条形码扫描仪
- android - Android:从UI线程启动一个工作线程挂起应用程序
- python - sleep_until 的 Python 版本
- javascript - 通过 php 和数组数据创建动态链接和 onClick
- c++ - 类中成员的类型似乎会影响类中其他成员的初始化
- c# - 如何从作为类属性的列表中返回元素
- encoding - 参数中编码特殊字符导致spring boot合约测试查询不匹配问题
- html - 尽管z-Index,鼠标悬停图像显示推送文本
- amazon-s3 - 在 AWS S3、cloudfront 和 route53 上使用掩码重定向