?
Solved

Dynamically Typed List

Posted on 2013-01-17
11
Medium Priority
?
35 Views
Last Modified: 2016-07-02
Hi There

I'm trying to create a static function in c# .net that I can use to turn a line of MySQL in to a List<T> where T is of a generic type.

I find myself repeatedly creating the following code for each type that I use it for (in this case, the type Train)

        private static List<Train> GetTrainListFromSQL(string sql)
        {
            DataTable dt = DB.GetTable(sql);
            List<Train> TrainList = new List<Train>();
            foreach (DataRow dr in dt.Rows)
            {
                TrainList.Add(new Train(Convert.ToInt32(dr["id"])));
            }
            return TrainList;
        }

        public static List<Train> AllTrains()
        {
            return GetTrainListFromSQL("SELECT * FROM trains WHERE deleted = 0 ORDER BY tt_time DESC");
        }

Is there a way where I can call just one common static function where I can pass any of my objects (maybe with a common interface) so that I can simply convert a database to a list<t> without having to clone the code and just change the type reference each time? I.e I have exactly the same method in my WebPage object called:

private static List<WebPage> GetWebPageListFromSQL(string sql)
        {
            DataTable dt = DB.GetTable(sql);
            List<WebPage> WebPageList = new List<WebPage>();
            foreach (DataRow dr in dt.Rows)
            {
                WebPageList.Add(new WebPage(Convert.ToInt32(dr["id"])));
            }
            return WebPageList;
        }


Thanks in advance!
0
Comment
Question by:terryatnexus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
11 Comments
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 1336 total points
ID: 38787869
I think the following is basically what you mean
        private static List<T> foo<T>()   //function that accepts generics, returns a list of generics
        {
            return new List<T>();
        }

//example of how to call the function
        private void x()
        {
            List<int> l = foo<int>(); 

Open in new window



You would need to add you SQL code, I did the above for brevity to show how it works
0
 

Author Comment

by:terryatnexus
ID: 38787943
That's really helpful thank you. I've got 95% the way there, I just have 1 problem with line that contains:

GenericList.Add(new typeof<T>(Convert.ToInt32(dr["id"])));


How do I create an instance of that type in order to add it to the list?

My New Code:

        private static List<T> GetListFromSQL<T>(string sql)   //function that accepts generics, returns a list of generics
        {
            DataTable dt = DB.GetTable(sql);
            List<T> GenericList = new List<T>();
            foreach (DataRow dr in dt.Rows)
            {
                GenericList.Add(new typeof<T>(Convert.ToInt32(dr["id"])));
            }

            return GenericList;
        }

        public static List<Train> AllTrains()
        {
            return GetListFromSQL<Train>("SELECT * FROM trains WHERE deleted = 0 ORDER BY tt_time DESC");
        }

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 38788003
        private static List<T> foo<T>() where T : new()  //requires T supports new
        {
            List<T> l = new List<T>();
            l.Add(new T());
            return l;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            List<int> l = foo<int>();

Open in new window

0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 

Author Comment

by:terryatnexus
ID: 38788015
Almost there - I need to pass the int in to the new() constructor - I currently get:

'T': cannot provide arguments when creating an instance of a variable

How can I pass the int in to the constructor?
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 664 total points
ID: 38788415
Change:

GenericList.Add(new typeof<T>(Convert.ToInt32(dr["id"])));

to:

GenericList.Add(new T(Convert.ToInt32(dr["id"])));

Open in new window


You cannot use new and typeof in the manner you are attempting.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 1336 total points
ID: 38788809
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        public abstract class MyBaseClass
        {
            public abstract void SetVal(int i);
        }

        public class MyClass : MyBaseClass
        {
            public int somevar;

            public MyClass() {}
            public override void SetVal(int i) { somevar = i; }
        }


        private  List<T> foo<T>() where T : MyBaseClass, new()
        {
            List<T> l = new List<T>();
            T x = new T();
            x.SetVal(42);
            l.Add(x);
            return l;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            List<MyClass> l = foo<MyClass>(); 
            
        }
    }
}

Open in new window



This is actually a quite complex looking thing - unfortunately I don't know an easier way.  (C'tors with parameters aren't allowed in generic methods apparently).

I've created a base abstract class to define a method - which is used to fill the actual generic object.  The generic method uses a generic which is of this type (you could use an interface instead - it might be better to do so).  So construction is two step: new followed by filling the empty object.
0
 

Author Comment

by:terryatnexus
ID: 38792138
I've managed to come up with my own working solution:

I've changed type T to an Interface that sets out the requirments for the method.

    public static List<IWebCoreObject> GetListFromSQL<IWebCoreObject>(string sql) where IWebCoreObject : new()
    {
        DataTable dt = DB.GetTable(sql);
        List<IWebCoreObject> GenericList = new List<IWebCoreObject>();
        foreach (DataRow dr in dt.Rows)
        {
            Type classType = typeof(IWebCoreObject);
            ConstructorInfo classConstructor = classType.GetConstructor(new Type[] { Convert.ToInt32(dr["id"]).GetType() });
            IWebCoreObject classInstance = (IWebCoreObject)classConstructor.Invoke(new object[] { Convert.ToInt32(dr["id"]) });
            GenericList.Add(classInstance);
        }
        return GenericList;
    }

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41682841
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 41682844
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question