ASP.NET MVC / C # - Нулевой оператор объединения, типы - PullRequest
1 голос
/ 19 декабря 2011

Я пытаюсь создать нумерацию страниц на своей странице. Пользователь может выбрать количество элементов, которые будут отображаться на странице, предпочтительный размер будет сохранен как 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; 

Что вызывает эту ошибку? Как это исправить?

Ответы [ 2 ]

6 голосов
/ 19 декабря 2011

Convert.ToInt32 просто возвращает int, а не int? - поэтому тип выражения:

size ?? Convert.ToInt32(...)

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

Если вы пытаетесь попробовать использовать файл cookie StoriesPageSize, но вы не знаете, присутствует он или нет, вы можете использовать:

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 винвариантная культура, поскольку на самом деле она не предназначена для того, чтобы быть видимой для пользователя или чувствительной к культуре.Вы должны убедиться, что вы сохранили куки-файл, используя также инвариантную культуру.

В любом случае, при наличии метода расширения (в статическом неуниверсальном классе верхнего уровня), вы можете использовать:

size = size ?? Request.Cookies.GetInt32OrNull("StoriesPageSize") ?? 10;
1 голос
/ 19 декабря 2011

Проблема в том, что результатом первой операции (size ?? Convert.ToInt32(Request.Cookies.Get("StoriesPageSize").Value)) является int.Затем вы используете нулевой оператор слияния между этим int и другим int, но так как int не может быть нулевым, он завершается неудачей.

Не имеет смысла использовать нулевой оператор слияния, если левая часть не может бытьnull, поэтому компилятор выдает ошибку.

Относительно того, как это исправить, вы можете переписать его так:

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