1

Is it possible to set the <T> type in a generic class using the type of another class, if both are known during compile time and will not change during runtime?

For example, I have lots of 3rd party UI grids in my app. Each grid has several types of event callback args that get returned in handler methods. They all are generics and get fed the class that they are displaying.

I have numerous grids displaying different types with a lot of identical methods, and I'm trying to simplify so that my boilerplate setup can be done just by changing the desired class in one spot.

Existing Code:

Comment selectedComment; //Comment is type that is displayed in grid and all args
Grid<Comment> commentGrid;

void RowSelected(RowSelectEventArgs<Comment> args)
    {
        // Some code here
    }

Desired Code (Example non-functioning

Comment selectedComment; //Comment is type that is displayed in grid and all args

Type type = typeof(selectedComment); //I want to use some sort of line to set all <T> in one spot

Grid<type> commentGrid;  //Is it possible to refers <T> to the holder variable 'type' above?

void RowSelected(RowSelectEventArgs<type> args)
    {
        // Some code here
    }

//Both sections that say <type> give error: The type or namespace could not be found.
aterbo
  • 432
  • 7
  • 24
  • Look up `MakeGenericType`. Basically you use Reflection to get Types of both `Grid` and whatever you want `T` to be and then use `MakeGenericType` to create a generic type from those two types – Flydog57 Nov 19 '21 at 23:06
  • Does this answer your question? [c# Creating an unknown generic type at runtime](https://stackoverflow.com/questions/8965893/c-sharp-creating-an-unknown-generic-type-at-runtime) – Henryk Budzinski Nov 19 '21 at 23:40
  • 1
    Do you or do you not know it at compile time? If you know it at compile time what is stopping you doing `Grid`? Perhaps you can shorten it with a type-def `using TDef = MyNamespace.Comment;` then you can use `Grid` and `RowSelectEventArgs` everywhere – Charlieface Nov 20 '21 at 20:28
  • @Charlieface I do know at compile time, and do not need to adjust at runtime. The code currently is using `Grid`, but I'm wondering if there is a more generic way. I have numerous grids, say `Grid`, `Grid`, `Grid`, etc. Each grid has numerous types of `Args` , say `RowSelectedArgs`, `ActionEventArgs`, etc. I'm hoping to be able to set all of the `` values (not sure the correct term for them) in spot on each page, and my next step would eventually pull all the common methods out to a helper class or something by passing the `` value. – aterbo Nov 21 '21 at 16:05
  • 1
    As I said, you can use a [*`using` alias directive*](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive) in a similar way to a `typedef` in C, by defining the types at the top of the file. Generally you don't actually need to redeclare all these things anyway (especially if you use `var`), because the `T` at the top of the class tree effectively sets it all the way down – Charlieface Nov 21 '21 at 16:43
  • @Charlieface Thank you, that appears to be working and allow me to set type in one location per file. Much appreciated. I had not used alias directives previously. If you write this as an answer, I'll accept it. – aterbo Nov 21 '21 at 17:07
  • @Flydog57 and Henryk thanks for the help, but these answers are for setting dynamically at runtime. I'm looking to simplify/streamline setting `` at compile time. – aterbo Nov 21 '21 at 17:11

1 Answers1

1

You can use a using alias directive at the top of your file, which will define the type everywhere in that file.

using T = MyNamespace.Comment;
T selectedComment;

Type type = typeof(T);

Grid<T> commentGrid;

void RowSelected(RowSelectEventArgs<T> args)
{
    // Some code here
}

T is probably a bad choice, you might want something slightly more descriptive

Charlieface
  • 52,284
  • 6
  • 19
  • 43
  • Thanks, it worked for me just by adding `@using T = MyNamespace.Comment;` at the top of the file (Razor component) and then dropping `` into all of the `Grid` and `EventArgs`. It worked without specifying the first two lines, but I can see why they are useful for other sections of the code and why you included. them. – aterbo Nov 21 '21 at 17:15