#c# #reflection #interface
#c# #отражение #интерфейс
Вопрос:
почему вызов метода путем отражения намного медленнее, чем создание интерфейса, а затем вызов его путем отражения. первая версия показывает утомительный способ, а другая версия показывает улучшенный способ??
// first version
class A
{
public void fn()
{
}
}
void Main(String[]x)
{
Type type = typeof(A);
object obj = Activator.CreateInstance(type);
type.InvokeMember("fn", BindingFlags.Public, null, obj, null);
}
//second verison
interface IA
{
void fn();
}
class A :IA
{
public void fn()
{
}
}
void Main(String []x)
{
Type type = typeof(A);
IA obj =(IA) Activator.CreateInstance(type);
obj.fn();
}
Комментарии:
1. Во втором примере вы не отражаете вызов метода; все, что вы делаете, это обычный вызов метода. Кроме того, вы не предоставили никаких тестов.
Ответ №1:
Вызовы методов на основе отражения выполняются чрезвычайно медленно, поскольку вам нужно выполнять поиск элементов и привязку параметров и другие вещи во время выполнения.
Методы интерфейса, напротив, вызываются с помощью обычной callvirt
инструкции с использованием vtable.
Комментарии:
1. как насчет метода invoke menber, какой метод он использовал?
2.
InvokeMember
, как и остальная частьType
класса, является отражением.
Ответ №2:
Для сравнения яблок с яблоками вызовите Type.getConstructor, чтобы получить объект ConstructorInfo и вызвать его для создания вашего объекта. Затем вы можете сохранить ConstructorInfo и повторно использовать. Активатор очень медленный в сравнении.
Отвечая на ваш вопрос о том, как работает способ отражения:
Activator выполняет поиск в метаданных загруженных сборок имени типа, соответствующего указанному вами. Затем он ищет конструктор, похожий на Type.getConstructor , который возвращает ConstructorInfo . Он вызывает этот конструктор и возвращает объект.
Затем, когда вы вызываете Type .InvokeMember, вы снова используете отражение, запрашивая метаданные класса, чтобы найти соответствующую сигнатуру метода. Это возвращается как MethodInfo, который затем вызывается.
Тяжелая работа в отражении — это не сам вызов, а поиск метаданных для типа, конструктора и метода. Вот почему я говорил, что вы можете выполнять относительно высокопроизводительные вызовы методов для отраженных объектов, повторно используя объекты ConstructorInfo и MethodInfo . Вы найдете многократный вызов MethodInfo .Вызов намного быстрее, чем ввод.InvokeMember
Комментарии:
1. Я не согласен. Если вы разбиваете вызов Activator и вызов invoke member на их фактические реализации, это включает получение ContructorInfo и MethodInfo . Интерфейсы используют или статический вызов метода, который не требует поиска MethodInfo