nullcheck真的可以在Statebag上使用吗?

时间:2018-11-13 09:52:28

标签: c# asp.net

public long MetaExtraData
{
    get { return (long)(ViewState["MetaData"] ?? 0); }
    set { ViewState["MetaData"] = value; }
}

当ViewBag不包含键“ MetaData”时,我返回“无法转换为长整数”异常。整个想法不是吗?处理这个?

当然,以下代码段也会引发强制转换错误。检查变量值时:o = null

public long MetaExtraDataInt
{
    get
    {
        object o = ViewState["MetaData"];
        return (long)(o ?? 0);
    }
    set { ViewState["MetaData"] = value; }
}

我知道问题很容易解决,但是我确实很想知道为什么?不要在手提包上工作

3 个答案:

答案 0 :(得分:2)

使用Nullable<int>属性而不是普通的int来进行空值运算符强制转换:

public int? MetaExtraDataInt
{
    get { return (int?)ViewState["MetaDataInt"] ?? 0; }
    set { ViewState["MetaDataInt"] = value; }
}

基于运算符优先级,空强制转换在强制转换为Nullable<int>之后执行,因此当ViewState["MetaDataInt"]包含空值时,它将返回零。

答案 1 :(得分:1)

如果docker run抛出(int)(ViewState["MetaDataInt"] ?? 0),则一定是因为您在状态包中的值不是InvalidCastException

这是因为:

  

装箱的T只能取消装箱到T(或可为空)。   取消包装后,它只是可以照常投射的值。

上面的引文摘自埃里克·利珀特(Eric Lippert)的Representation and Identity,我建议您阅读。

因此,如果您在“ MetaDataInt”状态包条目中存储的类型不是intint以外的其他类型,则即使该值可能强制转换为整数。

例如,如果它包含小数,则只能将其拆成小数。之后,您可以照常进行投射。

在拆开小数的示例情况下,以下内容将起作用:

int?

我建议您在调试器中查看return (int)(decimal)(ViewState["MetaDataInt"] ?? 0) 的类型,并相应地更改类型。

编辑:

我可以看到发生了什么。在屏幕快照中,您尝试取消装箱到很长的距离,但是合并的零是一个整数。这就是为什么您遇到异常的原因。

以下内容将解决您的特定问题。

ViewState["MetaDataInt"]

请注意return (long)(ViewState["ParentID"] ?? 0L) ,这是将long用作数字文字的方式。

您遇到了问题,因为您将0 0L与空int合并在一起,所以合并的结果也是一个对象,在这种情况下是装箱的{{1} }。装箱的object只能被拆箱到int,但是您试图将其拆箱到int。我们通过将0 int装箱来解决此问题,因此您可以将其装箱到很长的距离。

答案 2 :(得分:-2)

当ViewBag包含密钥时,它可以工作吗?尝试像这样强制转换viewstate返回值:

get { return (int)(ViewState["MetaDataInt"]) ?? 0); }