3

I have a project which stores values in SQL and later retrieves them for analysis. To keep track of what kinds of values might be stored, I created a class roughly like this:

private class DataField
{
    public string FieldName;
    public string FieldType;
}

When values are being read for analysis, a switch statement is used as follows (simplified):

switch (DataField.FieldType)
{
    case "int":
        List<int> InputData = new List<int>();
        // Populate list from DB
    break;
    case "bool":
        List<bool> InputData = new List<bool>();
        // Populate list from DB
    break;
}

Rather than maintain code in multiple places, I am looking for a way to get rid of the switch statement, but that means I need to dynamically create collections based on the type. Current that type is (naively?) a string, but I think I could improve this by changing the class:

private class ImprovedDataField
{
    public string FieldName;
    public Type FieldType;
}

And then dynamically create collections somehow:

Type DataType = typeof(DataField.FieldType);
List<DataType> InputData = new List<DataType>();
// Populate list from DB

This of course does not work, resulting in a Type or namespace name expected error.

Unfortunately I'm not very familiar with working with the Type class, nor generics nor anonymous types as I search for a solution (nothing seems to be appropriate).

How can I reduce duplication of code where the only difference in each switch statement branch is the type of variable collection being produced?

JYelton
  • 35,664
  • 27
  • 132
  • 191
  • possible duplicate of [C# Dynamic Generic Type](http://stackoverflow.com/questions/2078914/c-sharp-dynamic-generic-type) – nawfal Jan 17 '14 at 14:30

2 Answers2

6

If you want to create statically-typed collection of objects of type known at runtime, you need to use reflection. See i.e. this blog entry - that's the solution for creating List<T>:

public static IList CreateGenericList(Type collectionType)
{
    var listType = typeof(List<>).MakeGenericType(new[] { collectionType});
    return (IList) Activator.CreateInstance(listType);
}

So in your example:

Type dataType = DataField.FieldType;
IList inputData = CreateGenericList(dataType);
// Populate list from DB
NOtherDev
  • 9,542
  • 2
  • 36
  • 47
  • +1. I came here to type this :). Remember to consider how you will abstract the "Populate list from DB" step, though. Because if you use a switch statement or something for this, it kind of defeats the purpose. – Alec Jul 08 '11 at 20:45
  • @A.: This was very helpful and thus why I marked as accepted. I solved the issue by creating a `List` where `MyObject` contains `object` types, and passing the Type as an argument to the method that retrieves data, essentially moving the switch statement to a much smaller, more maintainable section. – JYelton Jul 08 '11 at 22:58
0

Why do you need a typed collection? Why not to use an ArrayList?

ArrayList list = new ArrayList()

list.Add( /* value read from database */ )
adontz
  • 1,428
  • 16
  • 36
  • Perhaps it doesn't need to be a typed collection. Could you show an example of what you mean? – JYelton Jul 08 '11 at 20:22
  • I think he means that since you have the FieldName (which I assume you use to pull the data from the database), you don't really need to know the type of data at all. You could just pull the data and store it in anything, whether that be ICollection or ArrayList. – Alec Jul 08 '11 at 20:48