Help with Enumeration, help with understanding IEumeration , IList and list along with .ToList

AppDev 20 Reputation points
2023-08-09T22:46:57.24+00:00

I have been stuck now for two months on this art of the project, I have created 3 messages that are different that relates to my research for a solution to my issue. Let me state that I am not a hard core programmer. I am some one that can build some applications in C# VBnet and MVC. But I don't know all the ins and outs and I get hung up on matters that don't seem to have good information that is easily understood. It is my hope that someone can explain some of this is an easy to understand non technical way . Thanks!

Ok Let me state that I know that the I prefix means that these are some sort of interface.

I am not good with interfaces as the programming I do don't require ultra advance things.

I have done lots of reading and online help but I just don't get the concept of these things and why we are using them.

I know when you use the MVC scaffolding it make index pages using to list. But things get really complex when you start bringing in @model IEnumerable

and stuff like that.

So in one of my projects I have had a tough time with understanding why these are being use. and how to pass what I want from the model to the controller .

In a non technical explanation can some one tell me what this is telling me, again IN a non technical way

            //See: https://stackoverflow.com/questions/1349012/initialize-ilistt-c-sharp
            IList vUE_WRITE_KBASE_SOURCE = new List<IList>();

In my own attempt to understand this... it seems like I am taking a variable and making it a List twice??

I am sure they cant be right..

I I make the var IList and then I am setting it equal to a list of IList interfaces???

I am sure that cant be right either..

I want to capture the result of each search into a list that I can pass pack into the view after the linq database searches are completed So I added

            IList Result = new List<IList>();

An I would have hope that each result would be stored in the new list that I could pass back.. The code complies but its not working as expected

                try
                {
                    //VUE_WRITE_KBASE_SOURCE vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Find(SearchInt);
                    //Fix this to have if not found.
                    var KBID = (from i in db.VUE_WRITE_KBASE_SOURCE where i.RSL_ID == SearchInt select new { i.REQ_REQUEST_ID }).FirstOrDefault();
                    vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Where(n => n.REQ_REQUEST_ID == KBID.REQ_REQUEST_ID).ToList();

                    Result.Add(vUE_WRITE_KBASE_SOURCE);
                }


Here is the controller

  [HttpPost]
        public ActionResult WISK(string SearchString)
        {

            int SearchInt;
            bool TestIsIt = Int32.TryParse(SearchString, out SearchInt);


            //Declear ViewModel
            //See: https://stackoverflow.com/questions/1349012/initialize-ilistt-c-sharp
            IList vUE_WRITE_KBASE_SOURCE = new List<IList>();


            IList Result = new List<IList>();


            if (SearchString == null)
            {
                //return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

                return View();
            }


            if (Int32.TryParse(SearchString, out SearchInt))
            {
                try
                {
                    //VUE_WRITE_KBASE_SOURCE vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Find(SearchInt);
                    //Fix this to have if not found.
                    var KBID = (from i in db.VUE_WRITE_KBASE_SOURCE where i.RSL_ID == SearchInt select new { i.REQ_REQUEST_ID }).FirstOrDefault();
                    vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Where(n => n.REQ_REQUEST_ID == KBID.REQ_REQUEST_ID).ToList();

                    Result.Add(vUE_WRITE_KBASE_SOURCE);
                }
                catch (Exception Ex)
                {
                    //vUE_WRITE_KBASE_SOURCE.Add(SearchString + " NO REQUEST WAS FOUND IN THE KNOWLEDGE WITH THIS ID NUMBER"); 
                }
            }


            if (SearchString is string)
            {
                try
                {
                    //Check Details
                    vUE_WRITE_KBASE_SOURCE = (from kbr in db.VUE_WRITE_KBASE_SOURCE where kbr.REQ_REQUEST_DETAILS.Contains(SearchString) select kbr).ToList();
                    Result.Add(vUE_WRITE_KBASE_SOURCE);

                }
                catch (Exception Ex)
                {
                    //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE OF USER REQUEST MATCHING " + SearchString);

                }

                //return View(db.VUE_WRITE_KBASE_SOURCE.ToList());

                try
                {
                    //Check Solutions
                    vUE_WRITE_KBASE_SOURCE = (from kbr in db.VUE_WRITE_KBASE_SOURCE where kbr.RSL_REQ_NOTES.Contains(SearchString) select kbr).ToList();

                    Result.Add(vUE_WRITE_KBASE_SOURCE);


                }
                catch (Exception Ex)
                {
                    //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE OF IT SOLUTIONS MATCHING " + SearchString);

                }


                //return View(vUE_WRITE_KBASE_SOURCE);
                  return View(Result);

            }

            else 
            {

                //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE MATCHING " + SearchString);
            }
            //Return ID Search
            //return View(vUE_WRITE_KBASE_SOURCE);
            return View(Result);
        }

This is the Error I Get

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[System.Collections.IList]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[DUST.Models.VUE_WRITE_KBASE_SOURCE]'.

User's image

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,598 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,404 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 74,146 Reputation points
    2023-08-10T02:19:17.31+00:00

    you need to understand types. a variable has a defined type. at compile and runtime, during assignment, a check is done that the types match. ignoring the assignment override that allows int to assigned to doubles, when

    a = b;

    b must implicitly be cast-able as the type of a at compile time.

    interface are special in that they define an abstract type, that is it defines properties and methods, but no implementation. you can not new an interface (or abstract class).

    lets look at some simple interface, class and inheritance examples:

    // define some interfaces 
    public interface ISayHello
    {
      string SayHello(); 
    }
    public interface ISayGoodBye
    {
       string SayGoodBye();
    }
    
    // define simple base classes to implement interfaces
    public class Test1Base : ISayHello
    {
       public string SayHello() => $"{WhoAmI()}> Hello";
       public virtual string WhoAmI() => "Test1Base";
     } 
    public class Test2Base : ISayGoodBye
    {
       public string SayGoodBye() => $"{WhoAmI()}> GoodBye";
       public virtual string WhoAmI() => "Test2Base";
    } 
    public class Test3Base : ISayHello, ISayGoodBye
    {
       public string SayHello() => $"{WhoAmI()}> Hello";
       public string SayGoodBye() => $"{WhoAmI()}> GoodBye";
       public virtual string WhoAmI() => "Test3Base";
    } 
    
    // define inheritance
    public class Test1 : Test1Base 
    {
       public override string WhoAmI() => "Test1";
    }
    public class Test2 : Test2Base 
    {
       public override string WhoAmI() => "Test2";
    }
    public class Test3 : Test2Base 
    {
       public override string WhoAmI() => "Test3";
    }
    

    now we can see what can be at construction

    var test = new ISayHello();         // error can not new interface 
    var test = new Test1Base();         // implicit type 
    Test1Base test = new Test1Base();   // explicit type
    Test1Base test = new Test2Base();   // error mismatched types
    Test1Base test = new Test3Base():   // error mismatched types
    Test1Base test = new Test1();       // downcast Test1 to Test1Base
    ISayHello test = new Test1Base();   // explicit implementation of interface
    ISayHello test = new Test2Base();   // error no implementation
    ISayHello test = new Test3Base();   // explicit implementation of interface
    ISayHello test = new Test3();       // explicit implementation of interface via inheritance 
    

    so what between defining as interface or class

    var test = new Test3();       // implicit type Test3
    test.SayHello();              // valid
    test.SayGoodBye();            // valid
    test.WhoAmI();                // valid
    
    ISayHello test = new Test3();// explicit type of interface
    test.SayHello();              // valid
    test.SayGoodBye();            // error 
    test.WhoAmi();                // error
    
    ISayHello test = new Test3();// explicit type of interface
    test.SayHello();              // valid
    test.SayGoodBye();            // error 
    test.WhoAmi();                // error
    
    // cast object to valid type
    ISayHello test = new Test3();     // explicit type of interface
    test.SayHello();                  // valid - interface
    ((ISayGoodBye)test).SayGoodBye(); // valid - cast to intface 
    ((Test3Base)test).SayGoodBye();   // valid - cast base class
    ((Test3)test).SayGoodBye();       // valid - cast to object actual class
    

    now lets look at your examples:

    IList vUE_WRITE_KBASE_SOURCE = new List<IList>(); 
    

    the variable is declare as type IList. a simple inference that allows collection operations where the items are type object

    the constructor is List<IList>. List<> is a generic that implements both IList and IList<>. This constructs a collection of IList types (lists of objects).

    so when you add to vUE_WRITE_KBASE_SOURCE, the item must be of type IList, but you can not create a new IList, you must use a class that implements IList.

    IList vUE_WRITE_KBASE_SOURCE = new List<IList>(); 
    vUE_WRITE_KBASE_SOURCE.Add(new List<int>());    // add a list of ints downcast to IList
    vUE_WRITE_KBASE_SOURCE.Add(new List<string>()); // add a list of strings downcast to IList
    

    your error message is because the model return to the view is of explicit type List<IList>, but the view is expecting IEnumberable<Models.VUE_WRITE_KBASE_SOURCE>, but you are pass collection of a collection of objects.

    you did:

    IList Result = new List<IList>();   
    IEnumberable<VUE_WRITE_KBASE_SOURCE> Model = Result;  
    

    but Result a list of lists of objects, can not be cast to a Collection of VUE_WRITE_KBASE_SOURCE.

    but you really wanted:

    IList Result = new List<IList<>();   
    @Model IEnumberable<IEnumberable<VUE_WRITE_KBASE_SOURCE>>
    

    but this fails because you can not do an implicit of IList to a collection of VUE_WRITE_KBASE_SOURCE.

    so you need to define the Model as IList or IList<IList> and use casting to access the items of the inner list, or define

    IList<IList<VUE_WRITE_KBASE_SOURCE> Result = new List<IList<VUE_WRITE_KBASE_SOURCE>();  
    @Model IEnumberable<IEnumberable<VUE_WRITE_KBASE_SOURCE>> 
    

    downcasts work.


  2. Lan Huang-MSFT 30,181 Reputation points Microsoft External Staff
    2023-08-11T08:41:01.39+00:00

    Hi @AppDev,

    I have read all your posts and it looks like you have successfully achieved what you want.

    I thought I could offer my thoughts to help you understand better.

    The first is the problem of type conversion, you cannot pass List<IList> to IEnumerable[DUST.Models.VUE_WRITE_KBASE_SOURCE]. So need to change IList to VUE_WRITE_KBASE_SOURCE.

    IList<VUE_WRITE_KBASE_SOURCE> vUE_WRITE_KBASE_SOURCE = new List<VUE_WRITE_KBASE_SOURCE>();

    For IList and list, I guess there is not much difference between them in your code, you can use either of them.

    So you can also use: List<VUE_WRITE_KBASE_SOURCE> vUE_WRITE_KBASE_SOURCE = new List<VUE_WRITE_KBASE_SOURCE>();

    When to use List and when use IList in C#

    • A List object allows you to create a list, add things to it, remove it, update it, index into it and etc. List is used whenever you just want a generic List where you specify object type in it and that's it.
    • IList on the other hand is an Interface. Basically, if you want to create your own type of List, say a list class called ProductList, then you can use the Interface to give you basic methods and structure to your new class. IList is for when you want to create your own, special sub-class that implements List.
    • IList is an Interface and cannot be instantiated. List is a class and can be instantiated. It means:
     IList<string> MyList = new IList<string>();
     List<string> MyList = new List<string>
    

    you can't use linq and return more that one result to the screen.

    Based on your code, it's not clear to me what exactly you want to achieve, so I changed your code according to two cases.

    The first one is to get all the data directly, and then search for all matching conditions.

    IList<VUE_WRITE_KBASE_SOURCE> vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.ToList();

    All Code

    [HttpPost]
            public ActionResult WISK(string SearchString)
            {
    
                int SearchInt;
                bool TestIsIt = Int32.TryParse(SearchString, out SearchInt);
                IList<VUE_WRITE_KBASE_SOURCE> vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.ToList();
                if (SearchString == null)
                {
                    return View();
                }
                if (Int32.TryParse(SearchString, out SearchInt))
                {
                    try
                    {
                        //VUE_WRITE_KBASE_SOURCE vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Find(SearchInt);
                        //Fix this to have if not found.
                        var KBID = (from i in db.VUE_WRITE_KBASE_SOURCE where i.RSL_ID == SearchInt select new { i.REQ_REQUEST_ID }).FirstOrDefault();
                        vUE_WRITE_KBASE_SOURCE = db.VUE_WRITE_KBASE_SOURCE.Where(n => n.REQ_REQUEST_ID == KBID.REQ_REQUEST_ID).ToList();
                    }
                    catch (Exception Ex)
                    {
                        //vUE_WRITE_KBASE_SOURCE.Add(SearchString + " NO REQUEST WAS FOUND IN THE KNOWLEDGE WITH THIS ID NUMBER"); 
                    }
                }
                if (SearchString is string)
                {
                    try
                    {
                        //Check Details
                        vUE_WRITE_KBASE_SOURCE = (from kbr in db.VUE_WRITE_KBASE_SOURCE where kbr.REQ_REQUEST_DETAILS.Contains(SearchString) select kbr).ToList();
                    }
                    catch (Exception Ex)
                    {
                        //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE OF USER REQUEST MATCHING " + SearchString);
    
                    }
                    try
                    {
                        //Check Solutions
                        vUE_WRITE_KBASE_SOURCE = (from kbr in db.VUE_WRITE_KBASE_SOURCE where kbr.RSL_REQ_NOTES.Contains(SearchString) select kbr).ToList();
                    }
                    catch (Exception Ex)
                    {
                        //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE OF IT SOLUTIONS MATCHING " + SearchString);
    
                    }
    
                }
                else
                {
    
                    //vUE_WRITE_KBASE_SOURCE.Add(" NO INFORMATION WAS FOUND IN THE KNOWLEDGE MATCHING " + SearchString);
                }
                return View(vUE_WRITE_KBASE_SOURCE);
            }
    

    The second is implemented according to your code logic, which is to add all Tolists to a list. (This design will cause data to appear multiple times, not recommended)

            [HttpPost]
            public ActionResult WISK(string SearchString)
            {
    
                int SearchInt;
    
                bool TestIsIt = Int32.TryParse(SearchString, out SearchInt);
                IList<VUE_WRITE_KBASE_SOURCE> vUE_WRITE_KBASE_SOURCE = new List<VUE_WRITE_KBASE_SOURCE>();
                if (SearchString == null)
                {
                    return View();
                }
                if (Int32.TryParse(SearchString, out SearchInt))
                {
                    try
                    {
                        var KBID = (from i in db.VUE_WRITE_KBASE_SOURCE where i.RSL_ID == SearchInt select new { i.REQ_REQUEST_ID }).FirstOrDefault();
                        var b = db.VUE_WRITE_KBASE_SOURCE.Where(n => n.REQ_REQUEST_ID == KBID.REQ_REQUEST_ID).ToList();
                        foreach (var userData in b)
                        {
                            vUE_WRITE_KBASE_SOURCE.Add(new VUE_WRITE_KBASE_SOURCE()
                            {
                                REQ_REQUEST_ID = userData.REQ_REQUEST_ID,
                                REQ_REQUEST_DETAILS = userData.REQ_REQUEST_DETAILS,
                                RSL_REQ_NOTES = userData.RSL_REQ_NOTES,
                                RSL_LOG_ENTRY_DATE = userData.RSL_LOG_ENTRY_DATE
                            });
                        }
                    }
                    catch (Exception Ex)
                    {
                    }
                }
                if (SearchString is string)
                {
                    try
                    {
                        var b = (from kbr in db.VUE_WRITE_KBASE_SOURCE where kbr.REQ_REQUEST_DETAILS.Contains(SearchString) select kbr).ToList();
                        foreach (var userData in b)
                        {
                            vUE_WRITE_KBASE_SOURCE.Add(new VUE_WRITE_KBASE_SOURCE()
                            {
                                REQ_REQUEST_ID = userData.REQ_REQUEST_ID,
                                REQ_REQUEST_DETAILS = userData.REQ_REQUEST_DETAILS,
                                RSL_REQ_NOTES = userData.RSL_REQ_NOTES,
                                RSL_LOG_ENTRY_DATE = userData.RSL_LOG_ENTRY_DATE
                            });
                        }
                    }
                    catch (Exception Ex)
                    {
                    }
                }
                else
                {
    
                }
                return View(vUE_WRITE_KBASE_SOURCE);
            }
    

    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.