C# Best Practice: List<T> of List<T> or List< List<T>> -- better way?

I know you can have a List< List<T> >.  But there is something about it that seems strange to me.

What I am wanting is to have a TableClass which has a List < Row Class >.   Each Row Class is a List< Cell Class >.

Is there a nicer / cleaner way to represent this other than:

TableClass<RowClass<CellClass>>

In other words:

  public class TableClass
    {
        public TableClass() { }

        public List<RowClass> Rows { get; set; }
    }

    public class RowClass
    {
        public RowClass() { }

        public List<CellClass> Cells { get; set; }
    }
    public class CellClass
    {
        public CellClass() { }        
    }

Open in new window



Better way?
LVL 5
Tom KnowltonWeb developerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

p_davisCommented:
I'm not sure of yor needs but if there isan index or primary key for each list you could use dictionary class.
Fernando SotoRetiredCommented:
It is not clear what you wish to accomplish and I am wondering if you are not trying to re-invent the wheel here, for example a DataTable object?
Tom KnowltonWeb developerAuthor Commented:
p_davis:

Not a bad idea.

Fernando Soto:

I know about DataTables.  I kind of [want] something like a DataTable - but not nearly as heavy in methods and features .. just basic navigation and querying, with a few additional attributes for my purposes.


Maybe it is a dumb question.  I just think   List<List<T>>    is kind of hookey - inelegant.
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Fernando SotoRetiredCommented:
Hi Tom;

Having a List<List<T>> is a reasonable option if it meets your needs. Not having more information on what you need it to do for you it would be difficult to suggest anything else.
it_saigeDeveloperCommented:
It may seem hookey, but it is essentially what a DataTable is (albeit a collection of rows with each row containing a collection of cells).

Just spitballing a similar data structure might look something like:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EE_Q29073347
{
    class Program
    {
        static void Main(string[] args)
        {
            var table = new Table<Animal>(from x in Enumerable.Range(0, 20)
                                          select new Row<Animal> {
                                              DataBoundItem = new Animal {
                                                  ID = x,
                                                  Name = $"Animal{x}",
                                                  AdoptionDate = DateTime.Now.AddDays(-(9 * x)),
                                                  HasShots = x % 2 == 0
                                              }
                                          }) { Name = "Animals" };

            Console.WriteLine($"Table: {table.Name}");
            foreach (var row in table.Select((r, i) => new { Row = r, Index = i }))
                Console.WriteLine($"{{ Index: {row.Index}; Row: {row.Row} }}");
            Console.ReadLine();
        }
    }

    class Table<T> : List<Row<T>>
    {
        public string Name { get; set; }

        public Table() : base() { ;}
        public Table(int capacity) : base(capacity) { ;}
        public Table(IEnumerable<Row<T>> collection) : base(collection) { ;}
    }

    class Row<T> : List<Cell>
    {
        T _dataBoundItem;
        public T DataBoundItem
        {
            get { return _dataBoundItem; }
            set
            {
                if (value == null)
                    value = default(T);
                this.AddRange(from property in typeof(T).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
                              select new Cell { Name = property.Name, Value = property.GetValue(value, null) });
            }
        }

        public override string ToString()
        {
            return $"{{ DataBoundItem: {DataBoundItem}; Cells: {{ {string.Join("; ", this)} }} }}";
        }
    }

    class Cell
    {
        public string Name { get; set; }
        public object Value { get; set; }

        public override string ToString()
        {
            return $"{{ Name: {Name}; Value: {Value} }}";
        }
    }

    class Animal
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime AdoptionDate { get; set; }
        public bool HasShots { get; set; }
    }
}

Open in new window


And produce the following output -Capture.PNG
-saige-
käµfm³d 👽Commented:
There's nothing odd about List<List<T>> to me. Sure, it's a lot to type (and potentially a lot to read). You could minimize how much you have to type by using a type alias at the top of your namespace (see below), but since most people don't use those you would need to weigh the benefit versus the potential obfuscation of your code.

namespace SomeNamespace
{
    using MyNiftyDataTable = List<List<CellClass>>;

    public SomeClass
    {
        private MyNiftyDataTable table;

        public SomeClass()
        {
            this.table = new MyNiftyDataTable();
        }
    }
}

Open in new window


Ultimately, I don't think a List<List<T>> is what you should use. There's probably a much more efficient data structure for your scenario, but you can only determine that when you determine how you will use the data.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.