Вызвать метод с помощью MethodInfo

Я хочу вызывать методы с определенным атрибутом. Поэтому я перебираю все сборки и все методы, чтобы найти методы с моим атрибутом. Работает нормально, но как мне вызвать определенный метод, если я получил только его MethodInfo.

AppDomain app = AppDomain.CurrentDomain;
Assembly[] ass = app.GetAssemblies();
Type[] types;
foreach (Assembly a in ass)
{
    types = a.GetTypes();
    foreach (Type t in types)
    {
        MethodInfo[] methods = t.GetMethods();
        foreach (MethodInfo method in methods)
        {
            // Invoke a certain method
        }
    }
}

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


person apparat    schedule 28.05.2009    source источник


Ответы (3)


Это кажется мне проблемой с точки зрения определения проблемы, а не кодирования.

Методы экземпляра зависят от того, для какого экземпляра они вызываются — нет смысла вызывать метод экземпляра, не заботясь о том, для чего он вызывается. (Как говорит Мартин, метод экземпляра, которому все равно, к какому экземпляру он вызывается, почти всегда должен быть статическим. Единственное немедленное исключение, которое я могу придумать для этого, — это виртуальные методы, где экземпляр неявно указывает, какую реализацию использовать.)

Выясните, что на самом деле означает в вашем контексте наличие аннотированного метода экземпляра. Почему вы все равно пытаетесь вызывать методы? Какова общая картина? Какой у вас контекст? Я сильно подозреваю, что вам понадобится некоторое понятие контекста — набора объектов, для которых вы можете вызывать методы экземпляра.

person Jon Skeet    schedule 28.05.2009
comment
Что я хочу сделать, так это пометить методы настраиваемым атрибутом, чтобы их можно было вызывать из командной строки. Где бы они ни были. Но я согласен с вами, что нет смысла вызывать одни и те же методы на серверных экземплярах, где метод не является статическим. Поэтому я буду использовать это в своего рода классе менеджера, который содержит набор этих объектов для вызова вызова для определенного экземпляра по параметрам. Я думаю, что это будет делать то, что я хочу. Спасибо - person apparat; 28.05.2009

Нестатические методы зависят от экземпляра, поэтому для вызова метода необходимо создать экземпляр класса. Если у вас есть возможность изменить код там, где он определен, и метод не требует, чтобы он был частью экземпляра (он не обращается к каким-либо нестатическим свойствам или методам внутри класса и не изменяет их), тогда наилучшей практикой будет в любом случае сделать метод статическим.

Предполагая, что вы не можете сделать его статическим, вам нужен следующий код:

    foreach (Type t in types)
    {
            object instance = Activator.CreateInstance(t);

            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo method in methods)
            {                    
                method.Invoke(instance, params...);    
            }
    }
person Martin Harris    schedule 28.05.2009
comment
фактически; Нестатические методы зависят от экземпляра. статические методы зависят от класса. - person Kris; 28.05.2009

На самом деле, я думаю, вам нужно создать список существующих объектов, а затем выполнить поиск по списку. Таким образом, когда вы создаете эти вызываемые объекты, вы должны сохранять их в списке (или, возможно, список должен быть списком объектов какого-либо другого типа, который также имеет описание вызываемого объекта). Затем вы можете просмотреть список во время выполнения, найти тот, который соответствует типу обрабатываемого вами события, а затем найти его methodInfo и вызвать .Invoke для информации о методе, предполагая, что это то, что вы хотите сделать. Вам также потребуется передать соответствующие аргументы, но вы можете сделать это, создав вектор объектов нужных типов.

person Ken Birman    schedule 17.03.2012