Распространенная ошибка — разница между явным и безопасным приведением

В этом посте я расскажу об ошибке, которую я встречал довольно часто, и которая может привести к тем уродливым исключениям « ссылка на объект не установлена ​​на экземпляр объекта ».

Вот вопрос. В чем разница между следующими 2 фрагментами кода?

var result = controller.Login() as ViewResult;
var result = (ViewResult)controller.Login();

Во время просмотра одного из видеороликов Mix 09 я видел довольно известного разработчика, который использовал первый тип приведения, когда он явно искал поведение второго. (Я не буду упоминать, кто это был)

Так в чем же разница? Если объект возвращается из Логина вызова метода (который является ActionResult в данном случае) действительно является экземпляром ViewResultкласса, как фрагменты будут вести себя точно так же. Однако, если приведение недопустимо (например, если возвращенный объект — RedirectToRouteResult ), первый фрагмент установит для объекта результата значение null , а второй — для исключения InvalidCastException .

Итог — если вы ожидаете, что объект будет определенного типа, выполните явное приведение (второй фрагмент). Если вы не уверены в типе объекта, либо проверьте тип, либо выполните безопасное приведение (первый фрагмент) и убедитесь, что результат равен нулю .

Я на самом деле использую это поведение довольно часто при выполнении TDD с MVC — первый тест, который я пишу для действия, обычно проверяет возвращаемое значение.

[Test]
public void LoginActionShouldReturnLoginView()
{
    var result = controller.Login() as ViewResult;

    Assert.IsNotNull(result);
    Assert.AreEqual("Login", result.ViewName);
}

Если бы я тестировал другую часть поведения, я бы просто сделал явное приведение.

Author: admin