Стоимость перегрузки метода в .Net - PullRequest
3 голосов
/ 27 февраля 2009

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

Так что, если у меня есть 3 метода, такие как:

Calculate (int)
Calculate (float)
Calculate (double)

и эти методы вызываются во время выполнения "динамически" в зависимости от того, что передается в метод Calculate, сколько будет стоить это разрешение перегрузки?

В качестве альтернативы я мог бы использовать один метод Calculate и внести изменения в тело метода, но я подумал, что для этого потребуется метод для оценки типа при каждом вызове.

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

РЕДАКТИРОВАТЬ: Спасибо всем. Jusdt одно, если что-то другое. Мне было интересно сказать, у вас есть DLL для этих методов и программа, написанная на C #, которая позволяет пользователю добавлять эти методы в качестве элементов пользовательского интерфейса (без указания типа). Таким образом, пользователь добавляет элемент пользовательского интерфейса Calculate (5), а затем Calculate (12.5) и т. Д., И приложение C # выполняет это, не будет ли по-прежнему никаких накладных расходов?

Ответы [ 7 ]

15 голосов
/ 27 февраля 2009

Что касается времени выполнения, это различные методы . Тоже самое что написано:

CalculateInt(int)
CalculateFloat(float)

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

9 голосов
/ 27 февраля 2009

Этот вопрос касается перегрузки метода, а не полиморфизма. Насколько я знаю, штраф за перегрузку метода отсутствует, поскольку компилятор выяснит, какой метод вызывать во время компиляции, основываясь на типе передаваемого ему аргумента.

Полиморфизм вступает в игру только тогда, когда вы используете производный тип вместо базового класса.

7 голосов
/ 27 февраля 2009

Во-первых, если ваш профилировщик не скажет вам, что есть проблема с производительностью, вы не должны жертвовать хорошим дизайном ради предполагаемого прироста производительности.

Чтобы ответить на ваш вопрос, разрешение вызовов методов не является динамическим. Он определяется во время компиляции, поэтому в этом отношении нет затрат. Единственная стоимость будет заключаться в потенциальном неявном приведении типа к типу параметра.

4 голосов
/ 27 февраля 2009

Перегрузка метода (то есть слот таблицы методов) не разрешается динамически во время выполнения, она разрешается статически во время компиляции, поэтому перегрузка методов обходится без затрат.

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

2 голосов
/ 27 февраля 2009

Во время выполнения нет "стоимости", потому что компилятор определяет, какой метод вызывать во время компиляции. Генерируемый IL-код вызывает метод, который принимает соответствующие параметры.

Возьмем для примера "

public class Calculator
{
    public void Calculate(int value)
    {
        //Do Something
    }
    public void Calculate(decimal value)
    {
        //Do Something
    }
    public void Calculate(double value)
    {
        //Do Something
    }
}

static void Main(string[] args)
{
    int i = 0;
    Calculator calculator = new Calculator();
    calculator.Calculate(i);
}

В IL выполняется следующий вызов для вычисления переменной «i»:

L_000b: callvirt instance void ConsoleApplication1.Calculator::Calculate(int32)

Обратите внимание, что в нем указан метод типа int32, который совпадает с типом переменной, переданной из метода Main.

Так что, если есть какая-то стоимость, то это только во время компиляции. Не беспокойся.

Как JaredPar , отмеченный ниже:

В вашем вопросе неверное представление. Перегруженные методы в C # не вызывается динамически во время выполнения. Все вызовы метода связаны статически при время компиляции. Отсюда нет «поиск» метода во время выполнения, это предопределено во время компиляции какая перегрузка будет вызвана.

1 голос
/ 27 февраля 2009

В вашем вопросе неверное представление. Перегруженные методы в C # не вызываются динамически во время выполнения. Все вызовы методов связаны статически во время компиляции. Следовательно, нет «поиска» метода во время выполнения, он предопределен во время компиляции, какая перегрузка будет вызвана.

Примечание: это немного меняется с C # 4.0 и динамически. С динамическим объектом возможно, что перегрузка будет выбрана во время выполнения в зависимости от типа объекта. Это не относится к C # 3.0 и ниже.

1 голос
/ 27 февраля 2009

3 различных метода производятся в IL в зависимости от типа. Единственная цена будет, если вы будете кастовать из одного типа в другой, но эта стоимость не будет значительной, если у вас нет большого количества дел. Так что вы можете придерживаться Calculate (double) и разыгрывать оттуда.

...