与三元运算符了解C#编译错误(Understanding C# compilation error

2019-07-17 19:14发布

我从复制下面的代码Wrox Professional ASP.NET 4.0 MVC 4本书,179页(第三章“了解安全向量在Web应用程序”),以使它的稍加修改protected和实用方法在我的抽象的应用程序-存储宽Controller

protected ActionResult RedirectToLocal(string returnUrl)
{
    if (Url.IsLocalUrl(returnUrl))
    {
        return Redirect(returnUrl);
    }
    else
    {
        return RedirectToAction("Index", "Home");
    }
}

上面的代码旨在确保从开放重定向攻击,这并不受这个问题的MVC应用程序。

该代码显然是良好的,编译,我相信它的工作原理。

当“智能”地改变上面的代码为以下单行问题出现

return (Url.IsLocalUrl(returnUrl)) ? Redirect(returnUrl) : RedirectToAction("Index", "Home");

一内衬上面是应该做的完全一样的扩展码(无,ReSharper的不建议我更换,这是我的计划)。

编译错误是: there is no implicit conversion between System.Web.Mvc.RedirectResult and System.Web.Mvc.RedirectToRouteResult

ReSharper的那么来帮助,并提出以下修改

return (Url.IsLocalUrl(returnUrl)) ? (ActionResult) Redirect(returnUrl) : RedirectToAction("Index", "Home");

现在的问题是“为什么我要投重定向方法”?

由于这两种RedirectRedirectToAction返回的子类ActionResult (通过F12验证)和子类是函数的返回值,应该是自动兼容。 或者至少,在我的C#的知识,无论是两个代码编译或他们都没有。

更一般的,这个问题可以改写如下:

假设我有A类,B和C

abstract class A {}
class B: A{}
class C: A{}

并假设下面的函数作品

private A Function(){
    if (condition) return new B();
    else return new C();
}

为什么以下的一行无法编译?

private A Function(){
    return (condition) ? new B(): new C();
}

Answer 1:

它不会编译,因为编译器决定什么回报型的一行代码是基于两个返回值之一。 由于B型不派生类型C,或周围的其他方式的,两种类型的并不相互排斥,和的,如果(作为一个整体)不能导出这样的返回类型。

如果你想做到这一点的一个班轮,你必须把返回值来要返回类型,它的类型是A.

private A Function(){
    return (condition) ? ((A)new B()): ((A)new C());
}

更新:我没有看到你已经做铸造你的问题,我的道歉。



Answer 2:

编译器预计在条件语句中相同的返回类型,因此,预计这两个是同一类型。 如果你投的选项的ActionResult,它会工作。 您可以通过仅铸造了最后一个与编译器相处。

return (Url.IsLocalUrl(returnUrl)) ? (ActionResult)Redirect(returnUrl) : (ActionResult)RedirectToAction("Index", "Home");


文章来源: Understanding C# compilation error with ternary operator