Приводит ли приведение ссылки на класс к ссылке на интерфейс какие-либо издержки? - PullRequest
2 голосов
/ 04 мая 2011

Говоря о приведении здесь, я имею в виду неявное приведение. Предположим, что класс B наследуется от A. Поскольку у нас есть только одно наследование в C #, при приведении ссылки на B к ссылке на A нам не нужно выполнять какие-либо «this» корректировки указателя или около того. Фактически, такое приведение не является операцией, потому что B равно A, все поля A имеют одинаковое смещение в объекте A и B.

И возникает вопрос: приводит ли приведение ссылки на B к ссылке на некоторый интерфейс, который реализует B, какие-либо издержки? Лично я не вижу причин, по которым это должно происходить, потому что интерфейсы не могут иметь полей (и, следовательно, указатель «this» не нужно настраивать, как в случае выше). Тем не менее иногда я слышу такие мнения, отсюда и этот вопрос.

1 Ответ

2 голосов
/ 04 мая 2011

Существует две стоимости:

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

В последнем случае я говорю об оптимизации JIT.Рассмотрим этот код:

string x = "hello";
object o = x;
string y = o.ToString();

Я подозреваю, что JIT завершается по-настоящему виртуальным вызовом метода, поиском в vtable и т. Д. Нет шансов на встраивание.

Если бы мы вызвали x.ToString() вместо этого, я ожидал бы, что JIT заметит, что String является конечным классом, и поэтому реализация String.ToString не может быть переопределена дальше - допускается вызов без просмотра vtable и, возможно, встраиваниетоже.

Это предположение, но об этом стоит подумать.Стоимость обработки объекта как более общего типа гораздо более вероятна, чем стоимость копирования ссылки.

...