Passing a general list to a class derived from a list

I created a class derived from List. However, when I tried to apply the class to another List object, I get a runtime error. My code is similar to the one below:

public class CategoryObj { public int CategoryID { get; set; } public string CategoryName { get; set; } public string Description { get; set; } } public class CategoryObjCollection:List<CategoryObj> { } public void Test() { CategoryObjCollection cat = new CategoryObjCollection(); using (NWDataContext db = new NWDataContext()) { var qry = (from c in db.Categories select new CategoryObj { CategoryID = c.CategoryID, CategoryName = c.CategoryName, Description = c.Description }).ToList(); cat = (CategoryObjCollection)qry; //runtime error Unable to cast object of type 'System.Collections.Generic.List`1[WindowsFormsApplication1.CategoryObj]' to type 'WindowsFormsApplication1.CategoryObjCollection'. } } 

I hope someone can help me with this. Thanks.

+7
c #
source share
4 answers

Why do you expect you can quit? The object is not an instance of CategoryObjCollection . Points of a reference type (when they actually call, rather than cause explicit conversions) should tell the compiler that, in your opinion, the runtime type of the object is actually compatible with the type you specify so that you can use members of this particular type (after the runtime test ) In this case, the ToList extension ToList simply creates a new List<T> .

To what extent is your CategoryObjCollection type designed to achieve in the first place? If it has any state other than a normal list, where do you expect this state to occur after a LINQ query? If it does not have any other state, does it really add any benefits? Maybe your type should contain a list, and not flow from it? Then you can create a new instance of the type using the query results.

In general, this is usually the smell of design coming from List<T> . It does not provide many ways to specialize in "its unusualness" (unlike, say, Collection<T> ). This is usually a sign that you should think about composition instead of inheritance.

+12
source share

try it

 public class CategoryObjCollection:List<CategoryObj> { public CategoryObjCollection(IEnumerable<CategoryObj> items) : base(items){} } cat = new CategoryObjCollection(qry); 
+6
source share

The cast will only work if you have implemented the conversion operator. But this is not a very effective approach.

Are you trying to create a type alias (e.g. in C ++ typedef)?

 using CategoryObjCollection = System.Collections.Generic.List<myNamespace.CategoryObj>; 

Now you can freely convert between CategoryObjCollection and List<CategoryObj> (this is the same type - only in different ways.

I would use another method to populate the list:

 db.Categories.ForEach(c => cat.Add(new CategoryObj() { CategoryID = c.CategoryID, CategoryName = c.CategoryName, Description = c.Description })); 
+3
source share

why are you throwing? Actually you shouldn't throw ... just add a loop over qry and populate the cat list up.

0
source share

All Articles