Accessing reflection generics and creating new instances of them?

9dj82nds

Member
Joined
Nov 1, 2022
Messages
10
Programming Experience
5-10
C#:
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => String.Equals(t.Namespace, "SomeNamespace", StringComparison.Ordinal)).ToArray();
foreach (Type T in types)
{
    //Neither of these will work
    var foo = Activator.CreateInstance(typeof(`What would I put here?`).MakeGenericType(T));
    var bar = Activator.CreateInstance(T.GetType().MakeGenericType(T));

I'm trying to work my way around the above code in order to generate the objects within a namespace, so I can use it for a generic system down the line:


C#:
    public class GenericObject<T>
    {
        public T[] GetData() => DeserializeJson.GetFiles<T>(typeof(T).Name);
        public GenericTab<T> tab;
    }


1. Is there any way I can do something like `new GenericObject<typeof(T)>()`
2. If not, is there any way I can get the classes from the `SomeNamespace` and assign them to `GenericObjects<T>` in a different way?
 
You are making the same mistake that many people make - that I made myself some time ago - in not differentiating between a data type and an instance of the Type class. The typeof operator returns the latter. It is an object that contains information about a data type and it is created and used at run time. A data type is an instruction to the compiler about how a variable can be used. When you use a generic type in your code and specify a generic type parameter, you have to use a data type because you're telling the compiler how that variable can be used. It couldn't be possible to use a Type object because that won't exist until run time so it can't help the compiler.
 
You are making the same mistake that many people make - that I made myself some time ago - in not differentiating between a data type and an instance of the Type class. The typeof operator returns the latter. It is an object that contains information about a data type and it is created and used at run time. A data type is an instruction to the compiler about how a variable can be used. When you use a generic type in your code and specify a generic type parameter, you have to use a data type because you're telling the compiler how that variable can be used. It couldn't be possible to use a Type object because that won't exist until run time so it can't help the compiler.
In terms of reflection I have access to the class by name is there any way I can do anything here in order to handle any kind of instancing? I feel like there's a way I can do this, since I have the assembly access.
 
It looks like you are trying to feed types T in SomeNamespace to GenericObject<T>, the example in documentation for Type.MakeGenericType does exactly this to create a specific Dictionary<TKey, TValue> type, see Type.MakeGenericType(Type[]) Method (System)
In your case it would be like this:
C#:
foreach (Type T in types)
{
    var generic = typeof(GenericObject<>);
    var specific = generic.MakeGenericType(T);
    var instance = Activator.CreateInstance(specific);

}
 
typeof(GenericObject<>);
This system doesn't use a reference to a "GenericObject" (I don't have a concrete class of any types I can use to set typeof other than the classesI get from the namespace) so I can't specifically set the type, the way I'm trying to do this is set the "GenericObject" generically.

This is all I can do (that won't work):
```
foreach (Type T in types)
{
var generic = typeof(T);
}
```
 
Last edited:
Variable 'generic' in my example is just a Type instance for a generic type, it can be discovered too.
You still must follow the same procedure: Supply type arguments to create a concrete type with MakeGenericType, from that you can create an instance. You can't create an instance from a generic type by itself.
 
Variable 'generic' in my example is just a Type instance for a generic type, it can be discovered too.
You still must follow the same procedure: Supply type arguments to create a concrete type with MakeGenericType, from that you can create an instance. You can't create an instance from a generic type by itself.
Why do you assume I don't know what `generic` is? Did you take any time to read my original code:

```
var foo = Activator.CreateInstance(typeof(`What would I put here?`).MakeGenericType(T));
var bar = Activator.CreateInstance(T.GetType().MakeGenericType(T));
```
I am doing what you already are suggesting this will not work, could you please show me how else you would do this, here: https://dotnetfiddle.net/jyTyYJ
Because all I'm getting is `xxx is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.`
 
You of course need a generic type definition to get a generic Type object from, that is what you have in first post with class GenericObject<T>. Your last Foo example is not a generic type, and I understand you want those types as type arguments to the generic type.
1. Is there any way I can do something like `new GenericObject<typeof(T)>()`
No, get the Type instance for the "GenericObject<>" (either with typeof or discover the Type) and use MakeGenericType method, feed it any Type instances as arguments.
 
No, get the Type instance for the "GenericObject<>" (either with typeof or discover the Type) and use MakeGenericType method, feed it any Type instances as arguments.
This is the entire point of why I made this question, how do I do that? I've said multiple times `typeof` doesn't work, and you can also test yourself. Could you possibly show me with the dotnet fiddle I posted? https://dotnetfiddle.net/jyTyYJ
 
Example types of use:
C#:
public class GenericObject<T> { }
public class A { }
Get the generic type with typeof
C#:
var generic = typeof(GenericObject<>);
or discover it any way you want:
C#:
var generic2 = Assembly.GetExecutingAssembly().GetType(generic1.FullName);
Do notice the inferred variable types is Type.
Then continue to use generic.MakeGenericType(Targs) as shown before to create the specific type and create instances from that.
C#:
var specific = generic.MakeGenericType(typeof(A));
var instance = Activator.CreateInstance(specific); // instance of GenericObject<A>
 
could you please show me how else you would do this, here: https://dotnetfiddle.net/jyTyYJ
Because all I'm getting is `xxx is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.`
In your fiddle, your class Foo is not a generic type.

I think you confused us because in post #1, you introduced us to GenericObject<T>. That got us down the path of trying to use C# generics. I suspect now that you are not actually trying to create "generic objects", but rather you are just trying to create "any object".
 
Example types of use:
C#:
public class GenericObject<T> { }
public class A { }
Get the generic type with typeof
C#:
var generic = typeof(GenericObject<>);
or discover it any way you want:
C#:
var generic2 = Assembly.GetExecutingAssembly().GetType(generic1.FullName);
Do notice the inferred variable types is Type.
Then continue to use generic.MakeGenericType(Targs) as shown before to create the specific type and create instances from that.
C#:
var specific = generic.MakeGenericType(typeof(A));
var instance = Activator.CreateInstance(specific); // instance of GenericObject<A>
I see your confusion, what you are suggesting is not what I am trying to do, if you read the actual code (If you did you would understand):

C#:
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => String.Equals(t.Namespace, "SomeNamespace", StringComparison.Ordinal)).ToArray();

That explains everything, I think you're not actually understanding what I'm trying to do and suggesting a solution that I already tried in my original question and said doesn't work.

I do not have access to your suggested "typeof(GenericObject<>);" because your "GenericObject" in my system is a runtime generic (I don't have access to tell my system to use a concrete type). In my example that is: `foreach (Type T in types)` All I have to work with is the types in the `types` variable that is returned from the Assembly.

`types` is a collection of runtime generics that I want to be able to use T is the type that I want to then use to create a type generic. I am not asking how to create a generic type. I am asking how

"Accessing reflection generics and creating new instances of them?"​

One of the major issues I have with the programming community in general is the fact that they don't actually read into a problem. They get stuck in their idea that their answer is right no matter what.
 
In your fiddle, your class Foo is not a generic type.

I think you confused us because in post #1, you introduced us to GenericObject<T>. That got us down the path of trying to use C# generics. I suspect now that you are not actually trying to create "generic objects", but rather you are just trying to create "any object".
I am trying to explain this in multiple ways but no one is really reading the code.

If anyone took two seconds to understand `types` is returning runtime generics. I don't have access to a concrete type. So suggesting something I already tried to do and posted in my first question is the reason why you guys are confused.


C#:
namespace Something{
    public class Foo{
        string bar;
    }
}

var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => String.Equals(t.Namespace, "Something", StringComparison.Ordinal)).ToArray();

I'll keep this simple then. How can I create a `Foo` object with `types[0]` (Without specifically using `Foo` or defining it anywhere, literally create a Foo from the type reference) from the above code? I'm 90% sure I can't do this, but wanted to confirm with the community if this is possible as there might be something I am missing.
 
How can I create a `Foo` object with `types[0]` from the above code?
That has nothing to do with generics, Foo is not a generic type. Activator.CreateInstance(types[0])
 
Back
Top Bottom