-1

I'm currently creating a machine learning engine that will run certain routines that are configured in the database. I want to create a method that will handle multiple types of IEnumerable that are passed from the DB as a string. I will have already defined the class type in the project, I just want to dynamically create the IEnumerable from the string name of the class.

Updated with more info:

Below is an example of the List I want to populate using dapper (.net core).

The machine learning prediction engine requires column attributes adding to the class so it knows what to do with it. I've pretty much accepted that I won't be able to dynamically create the class, I just want to create a List<"ClassName"> dynamically to save on code. I could write a case statement for every type of List I want to create but don't really want to.

Here's the class defintion:

class PriceChange24
    {
        [LoadColumn(0)]
        public Single Volume { get; set; }
        
        [LoadColumn(1)]
        public Single PriceChange1H { get; set; }

        [LoadColumn(2)]
        public Single PriceChange24H { get; set; }

        [LoadColumn(3)]
        public Single PriceChange7D { get; set; }

        [LoadColumn(4)]
        public Single PriceChange1HAvg { get; set; }

        [LoadColumn(5)]
        public Single PriceChange24HAvg { get; set; }

        [LoadColumn(6)]
        public Single PriceChange7DAvg { get; set; }

        [LoadColumn(7)]
        public Single RSI { get; set; }

        [LoadColumn(8), ColumnName("Label")]
        public bool GreaterThan10_24 { get; set; }

        public Single Volume24H { get; set; }

        public string Symbol { get; set; }

        public Single GBPValue { get; set; }

        public DateTime LastUpdated { get; set; }

}
  • 4
    What have you tried and what is not working for you? Also what you will need to do with this `IEnumerable` later? And please show us examples of strings. – Guru Stron Jul 20 '21 at 14:05
  • `IEnumerable` is an interface. You cannot create an interface object. You must create a collection implementing the interface (e.g., `T[]` or `List`). While you can create such an object with reflection, this is often not very useful, because you cannot program against such dynamically created types without using reflection again. So you end up doing everything with reflection from then on. – Olivier Jacot-Descombes Jul 20 '21 at 14:08
  • @OlivierJacot-Descombes there's nothing wrong with `doing everything with reflection from then on`; this is just a dynamic nature of C# and is a powerful feature for things like plug in management. – zaitsman Jul 20 '21 at 14:12
  • 3
    OK, once you've created this imaginary type, what would you do with it? How would you expect your code to process it? This is almost certainly a code smell here, but without know anything about your project structure, we can't really suggest a solution. – DavidG Jul 20 '21 at 14:16
  • @zaitsman, the point is that generics give you type safety at compile time. If you do reflection at runtime, you lose type safety. Therefore you can just as well use the non-generic `IEnumerable` and use collections of `object`. Doing reflection on generics defies the purpose of generics. But this of course depends on the usage which is unknown to us. See: [What is the XY problem?](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) (which I think this is). – Olivier Jacot-Descombes Jul 20 '21 at 14:25
  • @OlivierJacot-Descombes cmon now, it's not as if the OP is speaking about some weird generic, he wants a collection so he can enumerate over it with `foreach()` and/or LINQ. Of course there are advantages to be gained from doing this. And of course inside the loops you can use reflection. Sure this maybe an XY but the question itself is valid. I've done this myself plenty of times in various projects and see nothing wrong with it. – zaitsman Jul 20 '21 at 14:27
  • @zaitsman, As you don't know the type of the collection at compile time, you will end up in assigning it to an `IEnumerable` variable. You can foreach an `IEnumerable`, but what is the advantage of `IEnumerable` then? As DavidG says, we need more info from the OP. – Olivier Jacot-Descombes Jul 20 '21 at 14:38
  • Thanks for your replies. I've added a little more detail. – user2319379 Jul 20 '21 at 14:44

1 Answers1

0

IEnumerable is an interface so you will not be able to create an instance of it, but you can use a List<>.

You can do it like so:

using System;
using System.Collections.Generic;

// Here we are getting a reference to assembly using a known type.
// Alternatively, you can look at System.Reflection Assembly.GetExecutingAssembly
// or Assembly.GetEntryAssembly
var assemblyReference = typeof(Program).Assembly;
// Below is case sensitive and the type is meant to be public
var targetType = assemblyReference.GetType("Shoes");            

var instance = Activator.CreateInstance(typeof(List<>)
.MakeGenericType(targetType));

Console.WriteLine(instance.GetType()); // prints System.Collections.Generic.List`1[Shoes]
zaitsman
  • 8,984
  • 6
  • 47
  • 79