已经有几个类似的问题了,但我发现的问题中没有一个真正涉及到这个特定的话题,所以下面是……
我的理解是,应该始终尝试通过一个具体的类返回一个接口。不会说出背后的原因,已经有很多事情要做了。
但是,在IReadOnlyCollection
对ReadOnlyCollection
的情况下,我不确定是否应该遵循该规则。
一个IReadOnlyCollection
可以很容易地转换成一个List
,它.好吧..。破坏契约承诺的ReadOnly
方面。
然而,ReadOnlyCollection
不能转换为List
,但它意味着返回一个具体的类。
从长远来看,这真的有关系吗?在我看来,就像一样,在大多数情况下,是一个ReadOnly*/IReadOnly*
对象,它只由方法或只读属性返回。
因此,即使用户决定将其转换为其他对象(在IReadOnly*
对象的情况下)或使用LINQ创建某种类型的集合(在ReadOnly*
对象的情况下),公开ReadOnly*/IReadOnly*
对象的类也不可能接受返回。
那么这里的建议是,返回一个IReadOnly*
接口还是一个具体的ReadOnly*
类实例?
发布于 2017-07-18 11:42:37
您肯定应该尝试使您的公共方法返回接口。
如果您担心类的调用方将转换和修改您的内部结构,如本例中所示,那么类的内部队列不应该从外部访问:
public class QueueThing
{
private List<QueueItem> _cantTouchThis;
public IReadOnlyCollection<QueueItem> GetQueue()
{
return _cantTouchThis;
}
}
然后,您可以使用AsReadOnly()
返回一个来自私有List<T>
的新ReadOnlyList<T>
。
public class QueueThing
{
private List<QueueItem> _cantTouchThis;
public IReadOnlyCollection<QueueItem> GetQueue()
{
return _cantTouchThis.AsReadOnly();
}
}
现在调用方可以随意转换返回的值,他们将无法修改_cantTouchThis
成员(当然,在使用反射时除外,但无论如何,所有的赌注都取消了)。
考虑到许多类型可以实现一个接口,这种方法的用户绝对不应该假定将该方法的返回值转换为任何具体类型是安全的。
发布于 2017-07-18 11:07:14
只有当基础对象是该类型时,才能将IReadOnlyCollection<T>
转换为List<T>
。例如,ReadOnlyCollection<T>
也实现了IReadOnlyCollection<T>
。
因此,我的建议是返回IReadOnlyCollection<T>
,如果您担心调用方会错误地将其转换为不应该的内容,请确保底层类型为ReadOnlyCollection<T>
public IReadOnlyCollection<User> GetUsers()
{
return new ReadOnlyCollection<User>();
}
但是返回IReadOnlyCollection<T>
应该足够让函数调用者理解它应该是只读的。
请注意,您永远无法使用ReadOnlyCollection<T>
完全保护您的代码,调用方仍然可以使用反射访问内部列表并对其进行操作。
在这种情况下,唯一的选择是创建一个副本,如果列表并返回该副本。
发布于 2017-12-13 10:33:26
微软的指南这里声明:
ReadOnlyCollection是
ReadOnlyCollection<T>
的一个子类,✓确实使用IEnumerable<T>
来表示只读集合的属性或返回值。
因此,基本上,您应该返回ReadOnlyCollection<T>
。它在其他情况下指定了接口IEnumerable
,所以如果它打算使用接口IReadOnlyCollection<T>
,它就会这样说。
https://stackoverflow.com/questions/45164799
复制相似问题