явное приведение и AS
Вот меня и заинтересовал вопрос в чём отличае этих опираций в чём каждая из них лучше/хуже?
Сзаранее спасибо за дискуссию. :)
При явном приведении может возникнуть ексепшен если привести не удастся.
В .НЕТе есть is - проверить можно ли привести (в некорых языках instanceof). Результат операции - логический тип.
MyClass mobj = (MyClass)obj;
}
as - попробует привести тип и если ето удастса вернен переменную нужного типа, в противном случае вернет null. Потом проверяется значение переменной на null, что гараздо быстрее чем is.
if (mobj != null) {
чтото делаем
}
Приведение делается один раз и ексепшен не произойдет. Разве что не проверить на null и исипользовать. Но тогда ексепшен будет уже другой.
Собственно я вижу разницу только в том что при as не должен генерится ексепшен.
Причину возможной разници в быстродействии я не вижу, так что самому хотелось бы узнать. Надеюсь ahilles заметит тему и прольет свет на вопрос.
Тоесть в Делфи при простом приведении вобще можно что хочеш сделать ? А когдаже ошибка вылезет ? При испольновании обекта ?
ЗЫ. Кстати Михаил, с полсотней постов тебя. :)
к примеру можно сделать так:
procedure msg;
end;
procedure tc.msg;
begin
ShowMessage(string(self));
end;
var s:string;
s:='ggg';
tc(s).msg;
вот так
вот так
Гы. Забавно, неужели плохой код столько пророботать может. А если в msg к полям обекта обратится ?
Извените что надоедаю. Я как всегда на роботе и без средств розроботки под Делфи. Попробовать негде.
Жуть :). Так как же убить такой код ?
Ети четыре байта возможно адрес карты виртуальных методов ? Может тогда виртуальный метод вызвать чтоб ета прога накрылась ?
А то я сейчас вижу только две причини смерти: обращение к памяти только для чтения и выполнения недопустимой операцыи. По сути если обратится к виртуальному методу, то управление должно перейти чиртикуда.
в общем не хочу сам мучаться и писать об этом, приведу цитату из книги Марко Кэнту "Delphi 7: для профессионалов "
procedure TForm1.ButtonlClick(Sender: TObject);
begin
if Sender is TButton then
end;
В Delphi это довольно обычная практика, и я буду использовать ее в примерах этой книги. Два RTTI-оператора, is и as, чрезвычайно мощны, что может ввести в заблуждение: вы будете воспринимать их как стандартные конструкции программирования. Хотя они действительно мощны, необходимо ограничивать их использование только в исключительных случаях. При необходимости решить сложную проблему, включающую несколько классов, пробуйте сначала использовать полиморфизм. Только в отдельных случаях, где один полиморфизм не справляется, можно пробовать использовать RTTI-операторы. Не используйте RTTI вместо полиморфизма. Это неправильная практика программирования, которая ведет к снижению скорости выполнения программ. RTTI-операторы отрицательно влияют на производительность, поскольку для того, чтобы увидеть, является ли приведение типов корректным, им приходится пройти по всей иерархии классов. Как вы уже видели, вызовы виртуального метода требуют лишь поиска в памяти, что осуществляется гораздо быстрее.
P.S. если надо попроще, то вот что я про это писал когда был чайником :) _http://programmersclub.ru/is-as-gruzin :)
Операция is выполняет проверку соответствия типов и возвращает true или false. Если проверка прошла удачно, то можно использовать простое приведение
Операция as возвращает адрес или nil. Если проверка тиов прошла неудачно, то без проверки адреса неизбежно будет исключение "Ошибка доступа" (по нулевому адресу)
Кроме того, если исходные данные переданы ссылкой типа TObject, для проверки допустимости приведения можно использовать метод InheritsFrom (Другой_Тип). Либо его статичную реализацию TObject.InheritsFrom (Исходная_ссылка, Другой_Тип).