简体   繁体   中英

C# Generics List of List

Hi I have a simple issue with an sql application that I seem not to be capable of resolve. It involves the use of generics of which I am not too familiar with. I did researches here and on-line but I do not seem to find a fitting solution for my case.

I have two classes: Table and Field. I want Table to contain a List of Field and I want each Field to contain a List of RecordSet. The tricky part is that I want the user to choose which type of RecordSet to implement.

The Class Definition of Table is:

namespace DBlib
{
    public class DBTable<T>
    {
        public List<DBField<T>> FieldName = new List<DBField<T>>();

        public DBTable (string NameOfTable)
        {
        }

        public void AddField (string Name)
        {
            DBField<T> TempList = new DBField<T>();
            FieldName.Add(TempList);
        }
    }
}

The Class Definition of Field is:

namespace DBlib
{
    public class DBField<T>
    {
        public List<T> RecordSet = new List<T>();

        public DBField()
        {            
        }         
    }
}

With this code the user is forced cast the type when he is instantiating DBTable. This is not correct. I want the user to cast the type when the AddField method is invoked. Can you suggest a simple way to solve this issue?

UPDATE #1 I changed TempList as DBField in the Table Class definition. Sorry for the confusion there.

I want to add also this code to explain better what my issue is. Assuming the first Field of the table is an integer, the user should do:

namespace SpecifytheName
{
    public class User
    {
        DBTable<int> Table = new DBTable<int>(); 

        public User()
        {            
        }         
    }
}

Instead, I want the user to do:

namespace SpecifytheName
{
    public class User
    {
        DBTable Table1 = new DBTable("Table1"); 

        // SPECIFY THE TYPE OF FIELD1 ONLY AT THIS POINT
        Table1.AddField<int>("Field1");  //or something like this

        public User()
        {            
        }         
    }
}

I would generally solve this issue using a non-generic interface to store your fields.

So start with this interface:

public interface IDBField
{
    IList RecordSet { get; }
    Type FieldType { get; }
}

Now implement DBField<T> like this:

public class DBField<T> : IDBField
{
    public List<T> RecordSet = new List<T>();

    IList IDBField.RecordSet
    {
        get
        {
            return this.RecordSet;
        }
    }

    Type IDBField.FieldType
    {
        get
        {
            return typeof(T);
        }
    }      
}

Then you can implement DBTable like this:

public class DBTable
{
    public List<IDBField> FieldName = new List<IDBField>();

    public void AddField<F>(string Name)
    {
        FieldName.Add(new DBField<F>());
    }
}

You can use the FieldType property on IDBField to determine the type of the field and then use reflection as necessary to use the values of RecordSet appropriately.

The only way I can see this working is by not using Generics, but just use the Object class.

for example:

public class DBTable
{
    public List<DBField<Object>> FieldName = new List<DBField<Object>>();

    public DBTable (string NameOfTable)
    {
    }

    public void AddField(string Name)
    {
        List<DBField<Object>> TempList = new List<DBField<Object>>();
        FieldName.Add(TempList);
    }
}

This will mean you can use any type in the RecordSet object without restricting the type in the DBTable class.

I could be a bit off base here as I'm not sure what you're trying to achieve, for one you aren't going anything with the Name parameter passed into the AddField method, and you're TempList object isn't the same type as FieldName so it should throw some errors there..

EDIT:

I think I understand more clearly what you're trying to do, try this -

public class DBTable
{
    public List<DBField<Object>> FieldName = new List<DBField<Object>>();

    public DBTable (string NameOfTable)
    {
    }

    public void AddField<FieldType>(string Name)
    {
        DBField<FieldType> field = new DBField<FieldType>(Name);
        FieldName.Add(field);
    }
}

This way each Field (Column) is still forced to a type, but the DBTable isn't tied down to that same type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM