Вопрос по reflection, methodinfo, generic-method, generics, c# – @Jon: очень верно.

2

не позвонитьSomeObject.SomeGenericInstanceMethod<T>(T arg) ?

Есть несколько постов о вызове обобщенных методов, но не совсем так. Проблема заключается в том, что параметр аргумента метода ограничен универсальным параметром.

Я знаю, что если бы подпись была вместо

SomeObject.SomeGenericInstanceMethod<T>(string arg)

тогда я мог бы получить MethodInfo с

typeof (SomeObject).GetMethod("SomeGenericInstanceMethod", new Type[]{typeof (string)}).MakeGenericMethod(typeof(GenericParameter))

Итак, как мне получить MethodInfo, когда обычные аргументы имеют универсальный тип? Спасибо!

Кроме того, могут быть или не быть ограничения типа на универсальный параметр.

Ваш Ответ

2   ответа
11

Когда вы вызываете MethodInfo.Invoke, вы передаете все аргументы вobject[] в любом случае, это не значит, что вы должны знать типы во время компиляции.

Образец:

using System;
using System.Reflection;

class Test
{
    public static void Foo<T>(T item)
    {
        Console.WriteLine("{0}: {1}", typeof(T), item);
    }

    static void CallByReflection(string name, Type typeArg,
                                 object value)
    {
        // Just for simplicity, assume it's public etc
        MethodInfo method = typeof(Test).GetMethod(name);
        MethodInfo generic = method.MakeGenericMethod(typeArg);
        generic.Invoke(null, new object[] { value });
    }

    static void Main()
    {
        CallByReflection("Foo", typeof(object), "actually a string");
        CallByReflection("Foo", typeof(string), "still a string");
        // This would throw an exception
        // CallByReflection("Foo", typeof(int), "oops");
    }
}
Будет ли это работать, если есть несколько перегрузок для метода с именем "name"? smartcaveman
Что-то вроде: typeof (Test) .GetMethods (BindingFlags.Instance) .Where (x => x.IsGenericMethodDefinition & x.Name == name)? smartcaveman
@smartcaveman: попробуйте ParameterInfo.ParameterType.IsGenericType. Jon Skeet
@smartcaveman: Нет, вам нужно решить, какой позвонить. призваниеGetMethod(string, Type[]) может быть довольно сложно, когда типы параметров являются общими - я обычно используюGetMethods в сочетании с запросом LINQ, чтобы найти правильный метод. Jon Skeet
@smartcaveman: Ну, это не помогло бы, если быдва универсальные методы с тем же именем. В принципе, я не могу вам здесь сильно помочь, потому что я не знаю, как выхотеть чтобы иметь возможность определить правильный метод. Подумайте, как бы вы их разделили вручную, и напишите запрос. Jon Skeet
2

typeof (SomeObject).GetMethod(
       "SomeGenericInstanceMethod", 
        yourObject.GetType())  
                 // Or typeof(TheClass), 
                 // or typeof(T) if you're in a generic method
   .MakeGenericMethod(typeof(GenericParameter))

MakeGenericMethod Метод требует только, чтобы вы указали параметры универсального типа, а не аргументы метода.

Вы передадите аргументы позже, когда вызовете метод. Тем не менее, в этот момент они проходят какobjectтак что это опять не имеет значения.

@Jon: очень верно. Reed Copsey
Обратите внимание, что вызов GetMethod может завершиться ошибкой, еслиyourObject этоподтип требуемого, как в моем первом примере. Подтип может не удовлетворять ограничениям - например, рассмотретьFoo<T>(T item) where T : new() называется какFoo<object>("hello"), Мыне хочу позвонитьFoo<string>("hello") поскольку строка не имеет конструктора без параметров. Jon Skeet

Похожие вопросы