我有一些问题,关于参数类型应该在接口方法中应该是什么以及返回类型应该是什么 - 在C#中使用集合时。
假设我想获得A的集合并返回B的集合。我知道有拇指规则我们应该始终获得最通用的类型并返回最具体的类型。所以这里是一个例子:
public interface A
{
B[] MyMethod(IEnumerable<A> myAs);
}
以下是我从这一行得到的问题:
谢谢
我知道有拇指规则我们应该始终获得最通用的类型并返回最具体的类型。
不不不。绝对不。
正确的经验法则是,您需要来自呼叫者的最小可能合同,并且您向呼叫者提供最小的可接受合同。
前者是为了方便您的来电者,不应要求他们满足您不需要他们见面的合同。后一条规则可确保您更改实施细节的能力;通过返回最小可接受接口,接口的实现者可以选择对其实现选择最有效的实现细节。
当界面在我的系统内部时 - 我应该返回B集合的接口还是具体的?
您返回调用者可接受的最小合同。调用者是否需要ReadOnlyCollection,因为他们需要对其进行索引但不能写入它?他们需要一个数组,因为他们需要索引并编写它但不改变它的大小吗?它们是否需要列表,因为它们需要对其进行索引,编写并更改其大小?或者他们只是要求集合可以枚举?
你怎么知道来电者需要什么?您询问将要编写呼叫站点的开发人员。他们是您的客户,因此您在编写方法之前会收集他们的要求。
如果有他们不需要的服务,那么不要提供它们,因为提供这些不必要的服务需要付出代价。不要让你的来电者承担他们没有任何好处的成本!并且不要让接口的实现者必须提供不必要的服务的实现。
数组返回类型比列表返回类型更好吗?
如果调用者需要内容突变而不是大小突变,则数组优于列表。但两者都很糟糕。调用者真的需要索引和变异吗?大多数来电者都没有。更好的是返回一个IEnumerable
然后调用者可以调用ToArray
或ToList
,如果他们想要一个数组或列表。
大多数时候,明智的做法是返回一个序列。调用者可以决定是否希望承担将序列实现到列表或数组中的巨大内存开销。
myAs参数应该是我需要的最通用的接口类型,这意味着如果在我的代码中,myAs实际上是一个列表,那么参数应该是IEnumerable,ICollection还是IList?
它应该是MyMethod实现可以使用的最小的东西。如果MyMethod代表调用者改变了集合,那么你必须接受一个IList。如果没有,那就不要求你不打算使用的服务;这只会让来电者变得更难。