Czeshirecat
Czeshirecat

Reputation: 546

How do I use Activator.CreateInstance to do the following please

I use a similar style of code many times in my application to read in records from a database

WorkoutResultsRecord is inherited from a class called BaseRecord. One of the base constructors takes a IDataReader parameter to read fields into the class (as seen below).

What I want to do is define a generic function that will do the following for any/all of my 60+ xxxRecord type classes ie I can pass in a type as a parameter and it will return the correct type of objects as a typed List. Is it possible with Activator class? I've not used it before and my results just wouldn't compile

protected List<WorkoutResultsRecord> ReadRecordList(string sql, 
  IDbConnection connection)
{
  var results = new List<WorkoutResultsRecord>();
  using (IDbCommand command = GetCommand(sql, connection))
    using (IDataReader reader = command.ExecuteReader())
      while (reader.Read())
        results.Add(new WorkoutResultsRecord(reader));
  return results;
}

My really bad, failed attempt :(

private void sfsdf(Type type)
{
  List<typeof(type)> lst = new List<type>();
  Activator.CreateInstance(List<typeof(type)>);
}// function

Upvotes: 0

Views: 478

Answers (2)

Czeshirecat
Czeshirecat

Reputation: 546

The following is the full function with all the generics done as I wanted. This will save a lot of typing!! thanks very much

allResults = (List<WorkoutResultsRecord>)FillList(typeof(WorkoutResultsRecord), 
  sql, connection, new KVP("FROMDATE", fromUtf.Date),
      new KVP("TODATE", endDate.AddDays(1).Date));

IList FillList(Type type,string sql,IDbConnection connection,
  params KVP[] parameters)
{
  Type genericType = typeof(List<>).MakeGenericType(type);
  IList results = (IList)Activator.CreateInstance(genericType);

  using (var command= Command(sql,connection))
  {
    foreach(KVP parameter in parameters)
      CreateParam(command,parameter.Key,parameter.Value);
    using (IDataReader reader = command.ExecuteReader())
      while (reader.Read())
        results.Add(Activator.CreateInstance(type,reader));
  }
  return results;
}

Upvotes: 0

Rex
Rex

Reputation: 2140

this should work:

    private void sfsdf(Type type)
    {
        Type genericType = typeof(List<>).MakeGenericType(type);
        System.Collections.IList theList = (IList) Activator.CreateInstance(genericType);
        // do whatever you like with this list...
    }

Note: as the type is known at runtime only, it's not possible for you to declare a List when you write the code, so rather, use IList interface instead, but the created object theList should be of the expected type...

Upvotes: 1

Related Questions