Pass an Instantiated System.Type as a Type Parameter For a Generic Class

Pass An Instantiated System.Type as a Type Parameter for a Generic Class

You can't do this without reflection. However, you can do it with reflection. Here's a complete example:

using System;
using System.Reflection;

public class Generic<T>
{
public Generic()
{
Console.WriteLine("T={0}", typeof(T));
}
}

class Test
{
static void Main()
{
string typeName = "System.String";
Type typeArgument = Type.GetType(typeName);

Type genericClass = typeof(Generic<>);
// MakeGenericType is badly named
Type constructedClass = genericClass.MakeGenericType(typeArgument);

object created = Activator.CreateInstance(constructedClass);
}
}

Note: if your generic class accepts multiple types, you must include the commas when you omit the type names, for example:

Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);

Passing Type parameter to generic in C#

You can use MakeGenericType method to create a generic type using a Type instance:

var type = typeof(ValueCriterion<>).MakeGenericType(myType);

var instance = Activator.CreateInstance(type, 0);

Initialize a generic class with the generic type as a variable

It's possible, but you have to use reflection:

Type genericTypeDefinition = typeof(Rule<>);
Type genericType = genericTypeDefinition.MakeGenericType(_type);
Rule[] array = (Rule[])Array.CreateInstance(genericType, 0);

Pass dynamically type to generic template

Lets say CreateManager<T> is a method of type Foo:

public class Foo
{
private void CreateManager<T>(ServiceProvider serviceProvider,
DeviceCapability deviceCapability)
{
}
}

In order to dynamically invoke the generic method, you'll need to get the MethodInfo first, then call MakeGenericMethod with the actual type you want to pass (I choose string for the example)

var foo = new Foo();
var createManagerMethod = foo.GetType()
.GetMethod("CreateManager",
BindingFlags.Instance | BindingFlags.NonPublic);

var method = createManagerMethod.MakeGenericMethod(typeof(string));
method.Invoke(foo, new object[] { new ServiceProvider(), new DeviceCapability() });

Finally, call Invoke with the proper object instance and parameters.

Create instance of generic class with dynamic generic type parameter

I found very simple solution to problem. There is no need to cast object to specific type T, just use dynamic keyword instead of casting

   Type myGeneric = typeof(MyComparer<>);
Type constructedClass = myGeneric.MakeGenericType(T);
object created = Activator.CreateInstance(constructedClass);
dynamic comparer = created; // No need to cast created object to T

and then I can use comparer normally to call its methods like:

   return comparer.Equals(myResultAsT, correctResultAsT);

According to LueTm comments, it is probably possible to use reflection again and call comparer methods, but this solution looks much easier.

passing System.Type to generic type

var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;

You can't do that, you have no compile time information on what type you need, how do you expect to leverage it before the code is even running?

If you really want compile time type information of table you either know the generic type at compile time or you cover all possible execution paths considering all potential generic types your method must handle (horrendous, don't do that).

Using an interface won't work either. A hypothetical IIdEntity and a cast along the lines table as DbSet<IIdEntity> will never work because:

  1. Type variance is only allowed in interfaces and delegates, DbSet is not an interface.
  2. Even if you use IDbSet<TEntity>, this interface is invariant in TEntity so the following will always fail:

    class User: IIdEntity { ... }
    object o = someDbEntityOfUser;
    var db = o as IDbSet<IIdEntity> //will always be null.

The best options you have with your current setup are:

  1. Keep using reflection; use it to inspect the Id property of the entities.
  2. Use dynamic and simply let the runtime resolve the Id call.


Related Topics



Leave a reply



Submit