Casting of Generic List to a Class derived from a List

前端 未结 5 2041
萌比男神i
萌比男神i 2020-12-11 17:33

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

相关标签:
5条回答
  • 2020-12-11 17:44

    Why would you expect to be able to cast? The object isn't an instance of CategoryObjCollection. The point of reference type casts (when they're actually casting rather than invoking explicit conversions) is to tell the compiler that you believe the execution time type of the object is actually compatible with the type you specify, so that you can use members of that specific type (after the execution time test). In this case, the ToList extension method just creates a new List<T>.

    More to the point, what is your CategoryObjCollection type meant to achieve in the first place? If it has any state other than the normal list, where would you expect that state to come from after your LINQ query? If it doesn't have any other state, is it really adding any benefit? Maybe your type should actually contain a list rather than deriving from it? Then you could create a new instance of the type using the results of the query.

    In general, it's usually a design smell to derive from List<T>. It doesn't provide many ways to specialize its "listiness" (unlike, say, Collection<T>). It's usually a sign that you should be thinking of composition instead of inheritance.

    0 讨论(0)
  • 2020-12-11 17:52

    The cast would only work if you have implemented a conversion operator. But it is not a very effective approach.

    Are you trying to create a type alias (like in C++ typedef)?

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

    Now you can freely convert between CategoryObjCollection and List<CategoryObj> (which is the same type - only named differently.

    I would also use a different method to fill the list up:

    db.Categories.ForEach(c =>
        cat.Add(new CategoryObj()
            {
                CategoryID = c.CategoryID,
                CategoryName = c.CategoryName,
                Description = c.Description
            }));
    
    0 讨论(0)
  • 2020-12-11 17:52

    why are you casting ? You actually shouldn't be casting ....just add a loop over qry and fill your cat list up.

    0 讨论(0)
  • 2020-12-11 17:54

    try this

    public class CategoryObjCollection:List<CategoryObj>
    {
       public CategoryObjCollection(IEnumerable<CategoryObj> items) : base(items){}
    }
    
    
    cat = new CategoryObjCollection(qry);
    
    0 讨论(0)
  • 2020-12-11 17:56

    You can use this Extension Method

    public static M Cast<T, M>(this IEnumerable<T> input) where M : ICollection<T>, new()
    {
      var ret = new M();
      foreach(var item in input?? Enumerable.Empty<T>())
      {
        ret.Add(item);
      }
      return ret;
    }
    

    then you can use it like

    var qry = (from c in db.Categories
       select new CategoryObj
       {
           CategoryID = c.CategoryID,
           CategoryName = c.CategoryName,
           Description = c.Description
        }).Cast<CategoryObj,CategoryObjCollection>()
    
    0 讨论(0)
提交回复
热议问题