Denis Gladkikh
Russian   |  English

Использование оператора as (C#) и обработка Exceptions

Вчера первый раз в руках держал свою собственную копию бумажного варианта MSDN журнала. Новость, понятное дело, не эпическая, но хочу сказать, что именно бумажная копия журнала мотивирует на чтение MSDN статей, до этого ни разу я не читал столько статей из одного выпуска. В общем, на одной из первых страниц, в статье A Few of My Favorite Things... in the Entity Framework 4.2 DbContext я увидел следующий код:

var objectContext = (myDbContextInstance as IObjectContextAdapter).ObjectContext

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

var objectContext = ((IObjectContextAdapter)myDbContextInstance).ObjectContext

Чем этот вариант лучше предыдущего? А что если myDbContextInstance все-таки каким-то образом нельзя будет привести к типу интерфейса IObjectContextAdapter? Что будет в этом случае? В первом вариант мы получим всеми нами любимый NullReferenceException, так как оператор as вернет null в случае, если у него не удастся это приведение из типа DbContext в IObjectContextAdapter. Во втором случае мы честно получим тот самый InvalidCastException, который сразу же может дать нам понять, где именно, и в чем ошибка.

Вообще, после того, как я перешел из написания Enterprise приложений в написание Tools, я достаточно сильно пересмотрел то, как нужно обращаться к исключениям. В случае, если вы пишите Web морду, и приложение в какой-то момент не будет иметь доступа к файлу, то, скорее всего, вам бы хотелось, чтобы веб морда просто свалилась, клиент вам об этом сказал, и вы начали уже разбираться каким это образом так получилось, что у приложения появились какие-то проблемы с доступом (пример дурацкий до невозможности, но, надеюсь, вы ловите мою мысль). В случае тулзов – у вас есть куча клиентов, которые ставят свои приложения на всякие ожидаемые и неожидаемые окружения, вы понятия не имеете, что там пользователь будет делать, пока ваше приложение работает. Ожидать нужно всякое, и что пользователь захочет удалить файлы, которые открыты программой, и то, что этот файл он может заменить, и то, что он может изменить окружение в любой момент самыми различными действиями. В общем, в любой строке кода нужно понимать, что если этот код каким-то невероятным образом может вызвать исключение – его лучше поймать и обработать.


Вас также может заинтересовать

rss twitter

Комментарии (10)

Аноним ( ) #
avatar
Так это же Лерман - она и не такое пишет :) В ее "Programming Entity Framework" столько опусов... Тётенька, может, и хорошо разбирается в кишках EF, но код ее - совершенно вырвиглазный. А уж как начнет об архитектуре писать...
Алекс ( ) #
avatar
Кроме читабельности никакой разницы. Exception конечно другой, но все равно в StackTrace сразу лезем, так что тоже без разницы особой.
Denis Gladkikh ( ) #
avatar
Алекс в случае InvalidCastException можно сразу определить какая проблема (если хорошо знаешь код, то может быть даже не смотря код), с NullReferenceException - нужно точно посмотреть на строку, а что если это будет что-то типа такого?
var a = ((a as IFoo1).Property1 as IFoo2).Property2;
Сможете с NullReferenceException сказать где ошибка с лету? А с InvalidCastException, который вам точно скажет, что Cannot cast something to something.
Алекс ( ) #
avatar
Ну да, но ваш пример это уже слишком, ИМХО.

В общем, согласен наверное.
Denis Gladkikh ( ) #
avatar
Ну почему слишком, можно сделать и проще:
if ((a as Foo).IsSomething && (b as Foo).IsSomething)
{
  // ...
}
опять же два оператора as на одной строке, да и притом зачем я придираюсь все к двум операторам as на строке, можно же и так написать
var a = (x as Foo).Property1.Property2;
И уже тоже будет не понятно по какой именно причине произошел NullReferenceException.
Алекс ( ) #
avatar
Agreed.

Вопрос такой не по теме: вы не смотрели в сторону RoR? Я тут немного в шоке от того, с какой скоростью на нем делают прототипы сайтов. Возможно, в дальнейшем буду серьезно думать о том, чтобы набрасывать "рыбы" для заказчика на нем вместо ASP.NET.
Denis Gladkikh ( ) #
avatar
Алекс, неа, не смотрел. Вообще, в последнее время мало времени уделяю вебу... Время бы найти движок сайта обновить :(
Мурад ( ) #
avatar
Да. as/is равно как и RTTI это всегда плохой код. Не видел еще примеров, где их использование было бы оправдано.
Алексей ( ) #
avatar
оффтоп: Вы сами писали сайт?
Denis Gladkikh ( ) #
avatar
Алексей, для офтопов лучше использовать email. Ответ: да.
Добавить комментарий

Если вы хотите получать уведомления о новых комментариях к данному топику, укажите, пожалуйста, email и отметьте соответствующий пункт в форме. Если вы хотите добавить код в тексте комментария, то заключите его внутри тега [code]...[/code], более того можно уточнить язык, на котором написан данный код при помощи [code cs]...[/code], где вместо cs могут быть cs, html, xml, java, js, php, sql, cpp, css.

 

busy