可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a class called Product in my Business object and in another class i want to return a list of objects of this class.Which approach i should use ?
public static List<Product> GetProductList() { .... }
or create another class in my Business object namspace called ProductList which extends List <Products>
as follows:
public class ProductList :List<Products > { .... }
and use it there
public static ProductList GetProductList() { .... }
Is there any difference between these two ? How abt the memory allocation and performance ?
回答1:
There is a small overhead in having an extra type (ProductList
), but nothing huge. But it really depends on what you want to do. In many ways, ProductList
is still a bad idea since it burns List<T>
into the public API, and List<T>
isn't very extensible (none of the methods are virtual
, for example). Collection<T>
might have more extensibility options.
I'd argue in favor of abstraction or encapsulation:
public static IList<Product> GetProductList() {...} // abstraction; can return
// List<Product> if we want
or:
public class ProductList : IList<Product> {...} // encapsulation, but need to
// add a lot of dull code
It is a shame that C# doesn't make the encapsulation approach simple (I'm thinking "mixins").
Note that another trick (sometimes suitable, sometimes not) would be to use extension methods to add the illusion of extra methods on IList<Product>
... this is a tricky debate, so I'm just mentioning it, not saying "do this".
回答2:
The objective of generics was, among other things, to promote code reuse. Your first approach is more than appropriate.
The only times I've ever taken the second approach was when I had to add interface implementations to the collection (such as IDisposable), add extra functionality, or have had to serialize the collection to xaml.
回答3:
If you plan to add functionality to the list, such as more convenient lookup methods or product-specific queries, then return your own ProductList
class.
If not, there's no need to wrap it with your own class. Instead you should return an IList<Product>
or IEnumerable<Product>
, the more generic the better. This keeps the idea of returning a list or a collection of products but doesn't couple you to the actual collection implementation (a linked list, array, whatever).
回答4:
Microsoft Code Analysis recommends deriving from Collection<T> rather than List<T>.
This blog post explains why.
You might derive your own collection class from Collection<T> for the following reasons:
回答5:
If you just want to return the sequence of Products and would never use any functions on the List, I'd suggest you to use something like:
public static IEnumerable<Product> GetProductList()
回答6:
The amount of memory allocated should be identical, but the second option is more flexible as it allows you to add custom methods to the returned product list.
In the interest of encapsulation (or abstraction, thanks Marc), it is best practise to return an IList<Product>
, or to implement IList<Product>
, respectively.
回答7:
Personally I would go with your first suggestion simply because it means you aren't creating a new class. I do it like this as it prevents having loads of special purpose classes when one generic class would suffice.
public static IList<Product> GetProductList() { .... }