Вызов статического метода с использованием типа

#c# #generics #inheritance #static #abstract-class

#c#

Вопрос:

Как мне вызвать статический метод из Type , предполагая, что я знаю значение Type переменной и имя статического метода?

 public class FooClass {
    public static FooMethod() {
        //do something
    }
}

public class BarClass {
    public void BarMethod(Type t) {
        FooClass.FooMethod()          //works fine
        if (t is FooClass) {
            t.FooMethod();            //should call FooClass.FooMethod(); compile error
        }
    }
}
  

Итак, учитывая Type t , цель состоит в том, чтобы вызвать FooMethod() класс, который является Type t . В принципе, мне нужно отменить typeof() оператор.

Ответ №1:

Вам нужно вызвать MethodInfo.Invoke метод:

 public class BarClass {
    public void BarMethod(Type t) {
        FooClass.FooMethod(); //works fine
        if (t == typeof(FooClass)) {
            t.GetMethod("FooMethod").Invoke(null, null); // (null, null) means calling static method with no parameters
        }
    }
}
  

Конечно, в приведенном выше примере вы могли бы также вызвать FooClass.FooMethod , поскольку для этого нет смысла использовать отражение. Следующий пример имеет больше смысла:

 public class BarClass {
    public void BarMethod(Type t, string method) {
        var methodInfo = t.GetMethod(method);
        if (methodInfo != null) {
            methodInfo.Invoke(null, null); // (null, null) means calling static method with no parameters
        }
    }
}

public class Foo1Class {
  static public Foo1Method(){}
}
public class Foo2Class {
  static public Foo2Method(){}
}

//Usage
new BarClass().BarMethod(typeof(Foo1Class), "Foo1Method");
new BarClass().BarMethod(typeof(Foo2Class), "Foo2Method");    
  

Комментарии:

1. Спасибо, Игорь, это будет работать нормально (хотя я разочарован в C # — он выглядит совершенно нетипичным) В моем реальном коде есть много классов, которые могут быть в переменной типа, поэтому необходимо отражение.

Ответ №2:

Обратите внимание, что прошло уже 10 лет. Лично я бы добавил метод расширения:

 public static TR Method<TR>(this Type t, string method, object obj = null, params object[] parameters) 
    => (TR)t.GetMethod(method)?.Invoke(obj, parameters);
  

и тогда я мог бы вызвать его с:

 var result = typeof(Foo1Class).Method<string>(nameof(Foo1Class.Foo1Method));
  

Ответ №3:

Проверьте класс MethodInfo и методы GetMethod() в зависимости от типа.

Существует ряд различных перегрузок для разных ситуаций.