C# use System.Type as Generic parameter

c# call generic method with runtime type
c# create instance of generic type at runtime
c# pass generic type as parameter
c# call generic method with type variable
c# instantiate generic type
c# call generic method with dynamic type
c# cast object to generic type at runtime
c# dynamic cast to generic type

I have a list of types (System.Type) which need te be queried on the database.

For each of this types, I need to call the following extensionmethod (which is part of LinqToNhibernate):

Session.Linq<MyType>()

However I do not have MyType, but I want to use a Type instead.

What I have is:

System.Type typeOne;

But I cannot perform the following:

Session.Linq<typeOne>()

How can I use a Type as a Generic parameter?

You can't, directly. The point of generics is to provide compile-time type safety, where you know the type you're interested in at compile-time, and can work with instances of that type. In your case, you only know the Type so you can't get any compile-time checks that any objects you have are instances of that type.

You'll need to call the method via reflection - something like this:

// Get the generic type definition
MethodInfo method = typeof(Session).GetMethod("Linq", 
                                BindingFlags.Public | BindingFlags.Static);

// Build a method with the specific type argument you're interested in
method = method.MakeGenericMethod(typeOne);
// The "null" is because it's a static method
method.Invoke(null, arguments);

If you need to use this type a lot, you might find it more convenient to write your own generic method which calls whatever other generic methods it needs, and then call your method with reflection.

How to: Examine and Instantiate Generic Types with Reflection , In the following code, the type is obtained using the C# typeof operator In the type system, a generic type parameter is represented by an� In a generic type or method definition, a type parameter is a placeholder for a specific type that a client specifies when they create an instance of the generic type. A generic class, such as GenericList<T> listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type.

To do this you need to use reflection:

typeof(Session).GetMethod("Linq").MakeGenericMethod(typeOne).Invoke(null, null);

(assuming that Linq<T>() is a static method on the type Session)

If Session is actually an object, you'll need to know where the Linq method is actually declared, and pass in Session as an argument:

typeof(DeclaringType).GetMethod("Linq").MakeGenericMethod(typeOne)
     .Invoke(null, new object[] {Session});

Type.MakeGenericType(Type[]) Method (System), Remarks. The MakeGenericType method allows you to write code that assigns specific types to the type parameters of a generic type definition, thus creating a Type object that represents a particular constructed type. You can use this Type object to create run-time instances of the constructed type. You can call generic methods with types only known at execution time, but you have to use reflection: // For non-public methods, you'll need to specify binding flags too MethodInfo method = GetType().GetMethod("DoesEntityExist") .MakeGenericMethod(new Type[] { t }); method.Invoke(this, new object[] { entityGuid, transaction });

I have one general method which call Call Generic Method Through Reflection

/// <summary>
    /// This method call your method through Reflection 
    /// so i wil call the method like CallGenericMethodThroughReflection<Session>(assemblyQualifiedName,Linq,false,new[] { file }) 
    /// </summary>
    /// <typeparam name="T">Call method from which file</typeparam>
    /// <param name="assemblyQualifiedName">Your can get assemblyQualifiedName like typeof(Payroll.Domain.Attendance.AttendanceApplicationMaster).AssemblyQualifiedName</param>
    /// <param name="methodName"></param>
    /// <param name="isStaticMethod"></param>
    /// <param name="paramaterList"></param>
    /// <param name="parameterType">pass parameter type list in case of the given method have overload  </param>
    /// <returns>return object of calling method</returns>
    public static object CallGenericMethodThroughReflection<T>(string assemblyQualifiedName, string methodName,bool isStaticMethod ,object[] paramaterList,Type[] parameterType = null)
    {
        try
        {
            object instance = null;
            var bindingAttr = BindingFlags.Static | BindingFlags.Public;
            if (!isStaticMethod)
            {
                instance = Activator.CreateInstance<T>();
                bindingAttr = BindingFlags.Instance | BindingFlags.Public;
            }
            MethodInfo MI = null;
            var type = Type.GetType(assemblyQualifiedName);
            if(parameterType == null)
                MI = typeof(T).GetMethod(methodName, bindingAttr);
            else
                MI = typeof(T).GetMethod(methodName, bindingAttr,null, parameterType, null);//this will work in most case some case not work
            if (type == null || MI == null) // if the condition is true it means given method or AssemblyQualifiedName entity not found
                return null;
            var genericMethod = MI.MakeGenericMethod(new[] { type });
            return genericMethod.Invoke(instance, paramaterList);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

Using .NET Generics with a type derived at runtime – The Reformed , NET Generic types a lot and found them really useful. Only interested in how to use Generics with a runtime-derived type? layer modeller as primary keys for the hospital locations and various enums/parameters. As an example my test of system on a 1000 accesses then dynamic was between 120%� Generic methods can be overloaded on several type parameters. For example, the following methods can all be located in the same class: void DoWork() { } void DoWork<T>() { } void DoWork<T, U>() { } C# Language Specification. For more information, see the C# Language Specification. See also. System.Collections.Generic; C# Programming Guide

Generic Parameter Constraints for C#, Generics are most often used in conjunction with collections and methods that operate on them. A new namespace has been introduced, called System. Collections. Generic type parameters should have descriptive names. Good question, upvoted, I see MS using Type as a parameter for built-in operators in VB.NET e.g. trycast, and have often wished I could do that myself in C#/VB - in the fashion you describe. – Chalky Jun 18 '14 at 23:56

System.Type Class, Reflection; using System.Collections.Generic; // Define a base class with two type parameters. Generic interfaces can inherit from non-generic interfaces if the generic interface is contravariant, which means it only uses its type parameter as a return value. In the .NET Framework class library, IEnumerable<T> inherits from IEnumerable because IEnumerable<T> only uses T in the return value of GetEnumerator and in the Current property getter.

C# Generic Class, Generic Method Examples, C# program that describes generic class using System; class Test<T> { T _value; public Write(); // Use the generic type Test with a string type parameter. Generics (C# Programming Guide) 07/20/2015; 3 minutes to read +9; In this article. Generics introduce the concept of type parameters to .NET, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code.

Comments
  • I read about a solution which uses reflection to call the method. But I hoped there was another solution.
  • the invoke method returns an "Object". I am not able to query on this object untill I cast it to the correct Type. (Which would probably be IQueryable<T>) . How can I cast the object to the type I have?
  • @Jan: You can't - but then you wouldn't be able to use that type either, because you don't know the type at compile-time... this is where it may be worth you writing a generic method which does everything you want in a strongly-typed way, and calling that with reflection. Alternatively, does the non-generic IQueryable do what you need?
  • @Jon: Thanks, I will try writing my own generic method. Unfortunately the non-generic Iqueryable won't solve to problem.
  • @Jon: using my own generic method to call another generic method solved the problem