C# 从类库中的公共api返回数据列表的最佳实践是什么?
我有一个类库,其中包含一个向客户端(mvc、控制台应用程序等)返回列表的方法 现在,当我阅读时,我了解了以下几点: 不要在公共API中使用ArrayList或C# 从类库中的公共api返回数据列表的最佳实践是什么?,c#,C#,我有一个类库,其中包含一个向客户端(mvc、控制台应用程序等)返回列表的方法 现在,当我阅读时,我了解了以下几点: 不要在公共API中使用ArrayList或List 目前,使用我的类库api的客户机是MVC,它只是在其上循环,并对List中的某些属性执行string.format,但不更改原始列表中的任何内容 我曾考虑过IEnumerable,但客户端也可以将其强制转换为列表,然后对其进行操作,IReadOnlyList也是如此 MSDN设计指南没有规定,如果不是ArrayList或List,
List
目前,使用我的类库api的客户机是MVC,它只是在其上循环,并对List
中的某些属性执行string.format,但不更改原始列表中的任何内容
我曾考虑过IEnumerable
,但客户端也可以将其强制转换为列表,然后对其进行操作,IReadOnlyList也是如此
MSDN设计指南没有规定,如果不是ArrayList
或List
,那么什么才是公共API返回列表的合适集合
这是我向客户机公开的基类:
public abstract class BaseManager
{
//Other shared code
public abstract List<Statistics> GetStatistics();
}
public class Manager1 : BaseManager
{
public override List<Statistics> GetStatistics()
{
var stats = new List<Statistics>();
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
return stats;
}
}
公共抽象类BaseManager
{
//其他共享代码
公共摘要列表GetStatistics();
}
公共类管理器1:BaseManager
{
公共覆盖列表GetStatistics()
{
var stats=新列表();
添加(新的统计数据{….});
添加(新的统计数据{….});
添加(新的统计数据{….});
添加(新的统计数据{….});
返回统计;
}
}
根据经验,您希望尽可能少地向客户公开信息。如果您有一个接口可以保证您所允许的契约,那么您也不希望将它们绑定到特定的实现 因此,本着这种精神— 如果希望客户端只能读取使用
foreach
循环返回的数据,则返回一个。如果希望您的客户端能够访问
count
属性,请返回一个。如果您希望您的客户机能够基于其索引访问数据的特定部分,则返回一个 请注意,
IReadOnlyList
继承IReadOnlyCollection
,此接口继承IEnumerable
-因此所有这些选项都将允许使用foreach
,最后两个选项将允许使用count
(作为属性),最后一个将允许使用索引器
另外,请注意,您的底层类型仍然可以是列表
,因为它实现了IReadOnlyList
以及我提到的所有其他接口
另一件需要记住的事情是,在这种情况下,只读
并不意味着集合持有的所有成员都是不可变的-您仍然可以更改它们的属性(假设它们是可变类型)-但是集合本身是不可变的-您不能向其中添加或从中删除项
更新您的评论如下:
如果
IEnumerable
是一个列表,您可以向下转换它:
IEnumerable<int> myIEnum = new List<int>();
var myList = (List<int>)myIEnum;
派生类仍然可以在方法内使用列表,但将以IEnumerable
的形式返回该列表:
如果您熟悉.Net,您可能会注意到有许多名为
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.Collection
的类。它们符合文章中的条件,因此我认为它们是指南建议的
例如:
- System.Collections.Specialized.NameValueCollection
- System.Text.RegularExpressions.MatchCollection
- System.Collections.Generic.Dictionary.KeyCollection
- 创建一个类似于统计收集的
- 实现一个收集接口,如
ICollection
ReadOnlyCollection
。只需查看文档:(这不是框架/核心库提供的唯一只读集合类型;还有一些是针对特定应用场景的)但正如我在问题中提到的,如果我将返回IEnumerable,那么客户端仍然可以将其强制转换为List并对其进行操作。我已经更新了我的问题“如何返回List”您还可以创建一个List,然后使用.AsEnumerable()
扩展方法。@EluciusFTW您可以,但它不会有帮助。您还可以看到Enumerable.cs的属性,并看到AsEnumerable
只返回它得到的同一个对象-它接受IEnumerable
,并在需要时返回IEnumerable
-向上转换。那么您是说Statistics类应该实现这样的ICollection接口:public class Statistics:ICollection?统计收集类实现ICollection接口但在这种情况下,我必须实现ICollection接口的所有成员,对吗?是的。如果您认为大多数成员未被使用,请选择其他接口。“公共API”一词在
public abstract class BaseManager
{
//Other shared code
public abstract IEnumerable<Statistics> GetStatistics();
}
public class Manager1 : BaseManager
{
public override IEnumerable<Statistics> GetStatistics()
{
var stats = new List<Statistics>();
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
return stats;
}
}
public override IEnumerable<Statistics> GetStatistics()
{
var stats = new List<Statistics>();
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
stats.Add(new Statistics { .... });
foreach(var stat in stats)
{
yield return stat;
}
}