Как использовать typeof или GetType() как общий шаблон?

Если сложнее объяснить использование слов, взгляните на пример У меня есть общая функция, подобная этой

void FunctionA<T>() where T : Form, new()
{
}

Если у меня есть отраженный тип, как его использовать с указанной функцией? Я с нетерпением жду этого.

Type a = Type.GetType("System.Windows.Forms.Form");
FunctionA<a>();

Из-за этого вышеуказанный метод не работает.

Ответ 1

Ты не можешь. Обобщения в .NET должны быть решены во время компиляции. Вы пытаетесь сделать что-то, что решит их во время выполнения.

Единственное, что вы можете сделать, - это обеспечить перегрузку для FunctionA, которая принимает объект типа.


Хммм... комментатор прав.

class Program
{
    static void Main(string[] args)
    {
        var t = typeof(Foo);
        var m = t.GetMethod("Bar");
        var hurr = m.MakeGenericMethod(typeof(string));
        var foo = new Foo();
        hurr.Invoke(foo, new string[]{"lol"});
        Console.ReadLine();
    }
}

public class Foo
{
    public void Bar<T>(T instance)
    {
        Console.WriteLine("called " + instance);
    }
}

MakeGenericMethod.

Ответ 2

class Program
{
    static void Main(string[] args)
    {
        int s = 38;


        var t = typeof(Foo);
        var m = t.GetMethod("Bar");
        var g = m.MakeGenericMethod(s.GetType());
        var foo = new Foo();
        g.Invoke(foo, null);
        Console.ReadLine();
    }
}

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine(typeof(T).ToString());
    }
}

он работает динамически и может быть любого типа

Ответ 3

Несколько лет спустя и из блога MSDN, но это может помочь:

Type t = typeof(Customer);  
IList list = (IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(t)));  
Console.WriteLine(list.GetType().FullName); 

Ответ 4

Я решил эту проблему по-другому. У меня есть список класса, который инкапсулирует (реальную) функциональность Dapper. Он наследуется от базового класса, который является фиктивным классом для насмешек. Каждый метод в базовом классе переопределяется реальным классом. Тогда мне не нужно делать ничего особенного. Если в будущем я захочу сделать что-то особенное с SQLite или собственной базой данных в памяти, я всегда могу добавить это в базовый класс позже, если захочу.