0

Does anyone know if it's possible to pass in a Class Type dynamically to a Class that requires Type TObject?

My controller Class is declared like this:

public class DataController<TObject> where TObject : class

I don't know what "TObject" will be at runtime in some circumstances, so I would like to know if there is a way of doing something like what I am trying below? By the time this code hits, I know the Type and it's stored in "t", which I am passing into this method thus:

        private void RefreshGrid(Type t, DataGridView ctl)
    {
        DataController<t> cDataController = new DataController<t>();

            //... other stuff 

        cDataController = null;
    }

Obviously, the syntax here fails as "t" is a variable used like a type, the compiler rightly tells me.

Many thanks in advance.

Davy C
  • 639
  • 5
  • 16
  • 1
    Can't you make `RefreshGrid` generic too? (`private void RefreshGrid(DataGridView c) where T : TObject`) – Peter Bons Nov 04 '17 at 18:01
  • Thanks for your input, but I can't see how that would help. It doesn't matter if the RefreshGrid Method is of type , because I still need to instantiate the DataController inside the method with the real object (not ). – Davy C Nov 04 '17 at 19:41
  • Ok, can you please clarify more about how your code works. In your example, how and where is `RefreshGrid` called. You are not passing any real objects, only a type. You want to create a new instance then? Can you post the calling code? – Peter Bons Nov 04 '17 at 21:11
  • You don't bother to explain in your question where the type `t` comes from; making the method generic would work assuming the caller knows the actual type. If you really don't have _any_ code that knows at compile-time what the type is, you'll have to use `Activator`, per marked duplicate. Your question includes no information on how you expect to actually _use_ this instance, but be prepared for some difficulty. Once you go down the road of dynamic typing, you'll find that every step involves code where you'd like to be able to hard-code the type at compile-time, but can't. – Peter Duniho Nov 04 '17 at 23:16
  • Thanks Peter, I can see the truth in that final sentence, it hits the nail on the head perfectly. I've got it working using a whole mess of Reflection code, very ugly. I think there must be a better way of doing, but I appreciate that the question was lacking detail. Best wishes, Dave. – Davy C Nov 05 '17 at 01:21

1 Answers1

0

I'm not sure I completely understood your question, but if you want to create instance of open generic type, you can do it by using Activator

private void RefreshGrid(Type t, DataGridView ctl)
{
    var openGenericType = typeof(DataController<>);
    var genericType = openGenericType.MakeGenericType(t);
    var instance = Activator.CreateInstance(genericType); //Instance is type of DataController<T> where T is type of "t"
    //If you need to access instance's members, you can use System.Reflection
    //Other stuff...

    instance = null;
}

Maybe you can get better performance and readability if you specify more thoroughly what you want to achieve.

Darjan Bogdan
  • 3,780
  • 1
  • 22
  • 31
  • I have a Class that controls the interaction between the various views in the GUI and the database entities they are attached to. Actually, there is one class for each view, where I have the Database Entity Name, the View/Form name, and the DataGridView name on the Form too. Actually, my Class is in a list of these classes. I want to refresh all the views, but I don't want to individually do it, I want to do a "foreach" on each class instance, and send the "Type"/Entity and Grid into the Refresh function. I'll try your suggestion and many thanks. – Davy C Nov 04 '17 at 19:01
  • I forgot to mention that DataController requires a parameter of type DbContext. Thanks. – Davy C Nov 04 '17 at 20:00
  • I've added more detail to the question, many thanks in advance. – Davy C Nov 04 '17 at 20:24