ASP.NET MVC/C#-空合并运算符,类型

ASP.NET MVC/C#-空合并运算符,类型,c#,asp.net-mvc,null-coalescing-operator,C#,Asp.net Mvc,Null Coalescing Operator,我正在尝试在我的页面上创建分页。用户可以选择每页显示的项目数,然后首选大小将保存为cookie。但是,当我尝试在querystring参数和cookie之间进行选择时,出现了一个错误: public ActionResult Index(string keyword, int? page, int? size) { keyword = keyword ?? ""; page = page ?? 1; //Operator "??"

我正在尝试在我的页面上创建分页。用户可以选择每页显示的项目数,然后首选大小将保存为cookie。但是,当我尝试在querystring参数和cookie之间进行选择时,出现了一个错误:

    public ActionResult Index(string keyword, int? page, int? size)
    {
        keyword = keyword ?? "";
        page = page ?? 1;

        //Operator "??" cannot be applied to operands of type "int" and  "int"
        size = size ?? Convert.ToInt32(Request.Cookies.Get("StoriesPageSize").Value) ?? 10; 

是什么导致了这个错误?如何修复它?

Convert.ToInt32
只返回
int
,而不是
int?
-因此表达式的类型:

size ?? Convert.ToInt32(...)
类型为
int
。不能将不可为null的值类型用作null合并运算符表达式的第一个操作数-它不可能为null,因此第二个操作数(在本例中为10)永远不可能使用

如果您试图使用
StoriesPageSize
cookie,但不知道它是否存在,您可以使用:

public ActionResult Index(string keyword, int? page, int? size)
{
    keyword = keyword ?? "";
    page = page ?? 1;

    size = size ?? GetSizeFromCookie() ?? 10;
}

private int? GetSizeFromCookie()
{
    string cookieValue = Request.Cookies.Get("StoriesPageSize").Value;
    if (cookieValue == null)
    {
        return null;
    }
    int size;
    if (int.TryParse(cookieValue, CultureInfo.InvariantCulture, out size))
    {
        return size;
    }
    // Couldn't parse...
    return null;
}
如注释中所述,您可以编写一个扩展方法,使其更普遍地可用:

public static int? GetInt32OrNull(this CookieCollection cookies, string name)
{
    if (cookies == null)
    {
        throw ArgumentNullException("cookies");
    }
    if (name == null)
    {
        throw ArgumentNullException("name");
    }
    string cookieValue = cookies.Get(name).Value;
    if (cookieValue == null)
    {
        return null;
    }
    int size;
    if (int.TryParse(cookieValue, CultureInfo.InvariantCulture, out size))
    {
        return size;
    }
    // Couldn't parse...
    return null;
}
请注意,我已将代码更改为使用不变区域性-在不变区域性中传播cookie中的信息是有意义的,因为它实际上并不意味着用户可见或对区域性敏感。您还应该确保使用不变区域性保存cookie

无论如何,只要有了扩展方法(在静态非泛型顶级类中),您就可以使用:

size = size ?? Request.Cookies.GetInt32OrNull("StoriesPageSize") ?? 10;

Convert.ToInt32
只返回
int
,而不是
int?
-因此表达式的类型:

size ?? Convert.ToInt32(...)
类型为
int
。不能将不可为null的值类型用作null合并运算符表达式的第一个操作数-它不可能为null,因此第二个操作数(在本例中为10)永远不可能使用

如果您试图使用
StoriesPageSize
cookie,但不知道它是否存在,您可以使用:

public ActionResult Index(string keyword, int? page, int? size)
{
    keyword = keyword ?? "";
    page = page ?? 1;

    size = size ?? GetSizeFromCookie() ?? 10;
}

private int? GetSizeFromCookie()
{
    string cookieValue = Request.Cookies.Get("StoriesPageSize").Value;
    if (cookieValue == null)
    {
        return null;
    }
    int size;
    if (int.TryParse(cookieValue, CultureInfo.InvariantCulture, out size))
    {
        return size;
    }
    // Couldn't parse...
    return null;
}
如注释中所述,您可以编写一个扩展方法,使其更普遍地可用:

public static int? GetInt32OrNull(this CookieCollection cookies, string name)
{
    if (cookies == null)
    {
        throw ArgumentNullException("cookies");
    }
    if (name == null)
    {
        throw ArgumentNullException("name");
    }
    string cookieValue = cookies.Get(name).Value;
    if (cookieValue == null)
    {
        return null;
    }
    int size;
    if (int.TryParse(cookieValue, CultureInfo.InvariantCulture, out size))
    {
        return size;
    }
    // Couldn't parse...
    return null;
}
请注意,我已将代码更改为使用不变区域性-在不变区域性中传播cookie中的信息是有意义的,因为它实际上并不意味着用户可见或对区域性敏感。您还应该确保使用不变区域性保存cookie

无论如何,只要有了扩展方法(在静态非泛型顶级类中),您就可以使用:

size = size ?? Request.Cookies.GetInt32OrNull("StoriesPageSize") ?? 10;

问题是第一个操作(
size??Convert.ToInt32(Request.Cookies.Get(“StoriesPageSize”).Value)
)的结果是一个int。然后在这个int和另一个int之间使用Null合并运算符,但由于int不能为Null,因此它失败

如果左侧不能为Null,则使用Null合并运算符没有意义,因此编译器会给出一个错误

关于如何修复它,您可以这样重写它:

size = size ?? (Request.Cookies.Get("StoriesPageSize") != null ? Convert.ToInt32(Request.Cookies.Get("StoriesPageSize").Value) : 10);

问题是第一个操作(
size??Convert.ToInt32(Request.Cookies.Get(“StoriesPageSize”).Value)
)的结果是一个int。然后在这个int和另一个int之间使用Null合并运算符,但由于int不能为Null,因此它失败

如果左侧不能为Null,则使用Null合并运算符没有意义,因此编译器会给出一个错误

关于如何修复它,您可以这样重写它:

size = size ?? (Request.Cookies.Get("StoriesPageSize") != null ? Convert.ToInt32(Request.Cookies.Get("StoriesPageSize").Value) : 10);

你要扔掉SizeFromCookie另一个函数(convert.ToInt32或类似文件中是否存在允许结果为null的int的重载?@domanokz:我不知道-请记住,您需要考虑两种不同的情况:没有匹配的cookie,也没有可解析的值。您可以轻松编写通用方法(可能是
CookieCollection
上的一个扩展方法)返回
int?
。哇!是Jon Skeet!不管怎样,是的,你是对的,我可以从
null
获取
值。谢谢!是的,这只是为了可读性,特别是因为你的代表意味着人们可能会在你的代码中读取各种内容(我知道在给出上述评论之前,我总是额外检查几次)您要放弃SizeFromCookie另一个函数吗(convert.ToInt32或类似文件中是否存在允许结果为null的int的重载?@domanokz:我不知道-请记住,您需要考虑两种不同的情况:没有匹配的cookie,也没有可解析的值。您可以轻松编写通用方法(可能是
CookieCollection
上的一个扩展方法)返回
int?
。哇!是Jon Skeet!不管怎样,是的,你是对的,我可以从
null
获取
值。谢谢!是的,这只是为了可读性,特别是因为你的代表意味着人们可能会在你的代码中读取各种内容(我知道在给出上述评论之前,我总是多检查几次)更好地包装在Try/Catch中,您有可能引发FormatException、InvalidCastException或OverflowException更好地包装在Try/Catch中,您有可能引发FormatException、InvalidCastException或OverflowException相关:相关: